From ebd8f35cc752ba50851245c9e8281867ae04037b Mon Sep 17 00:00:00 2001 From: Danilo Burbano Date: Tue, 10 Dec 2024 21:05:07 -0500 Subject: [PATCH 1/6] [SPARKNLP-1094] Adding support to read Word files --- build.sbt | 6 +- project/Dependencies.scala | 7 +- python/sparknlp/reader/sparknlp_reader.py | 7 + python/test/sparknlp_test.py | 15 +- .../com/johnsnowlabs/reader/ElementType.scala | 4 +- .../johnsnowlabs/reader/SparkNLPReader.scala | 8 +- .../com/johnsnowlabs/reader/WordReader.scala | 178 ++++++++++++++++++ .../johnsnowlabs/reader/util/DocParser.scala | 73 +++++++ .../johnsnowlabs/reader/util/DocxParser.scala | 136 +++++++++++++ .../johnsnowlabs/reader/WordReaderTest.scala | 67 +++++++ 10 files changed, 495 insertions(+), 6 deletions(-) create mode 100644 src/main/scala/com/johnsnowlabs/reader/WordReader.scala create mode 100644 src/main/scala/com/johnsnowlabs/reader/util/DocParser.scala create mode 100644 src/main/scala/com/johnsnowlabs/reader/util/DocxParser.scala create mode 100644 src/test/scala/com/johnsnowlabs/reader/WordReaderTest.scala diff --git a/build.sbt b/build.sbt index 9ca49803ae0eb7..d3913301c73a22 100644 --- a/build.sbt +++ b/build.sbt @@ -158,7 +158,11 @@ lazy val utilDependencies = Seq( azureIdentity, azureStorage, jsoup, - jakartaMail + jakartaMail, + poiDocx + exclude ("org.apache.logging.log4j", "log4j-api"), + scratchpad + exclude ("org.apache.logging.log4j", "log4j-api") ) lazy val typedDependencyParserDependencies = Seq(junit) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b7c62a2db8bbff..abca4bc5fd08a2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -134,10 +134,15 @@ object Dependencies { val llamaCppSilicon = "com.johnsnowlabs.nlp" %% "jsl-llamacpp-silicon" % llamaCppVersion val llamaCppAarch64 = "com.johnsnowlabs.nlp" %% "jsl-llamacpp-aarch64" % llamaCppVersion - val jsoupVersion = "1.18.1" + val jsoupVersion = "1.18.2" val jsoup = "org.jsoup" % "jsoup" % jsoupVersion val jakartaMailVersion = "2.0.1" val jakartaMail = "com.sun.mail" % "jakarta.mail" % "2.0.1" + + val poiVersion = "4.1.2" + val poiDocx = "org.apache.poi" % "poi-ooxml" % poiVersion + val scratchpad = "org.apache.poi" % "poi-scratchpad" % poiVersion + /** ------- Dependencies end ------- */ } diff --git a/python/sparknlp/reader/sparknlp_reader.py b/python/sparknlp/reader/sparknlp_reader.py index 55e8ffc9174337..71e3596c25aaa4 100644 --- a/python/sparknlp/reader/sparknlp_reader.py +++ b/python/sparknlp/reader/sparknlp_reader.py @@ -111,4 +111,11 @@ def email(self, filePath): raise TypeError("filePath must be a string") jdf = self._java_obj.email(filePath) dataframe = self.getDataFrame(self.spark, jdf) + return dataframe + + def doc(self, docPath): + if not isinstance(docPath, str): + raise TypeError("docPath must be a string") + jdf = self._java_obj.doc(docPath) + dataframe = self.getDataFrame(self.spark, jdf) return dataframe \ No newline at end of file diff --git a/python/test/sparknlp_test.py b/python/test/sparknlp_test.py index e99fe491a00335..3b2ee58e22bfce 100644 --- a/python/test/sparknlp_test.py +++ b/python/test/sparknlp_test.py @@ -73,4 +73,17 @@ def runTest(self): email_df = sparknlp.read().email(self.email_file) email_df.show() - self.assertTrue(email_df.select("email").count() > 0) \ No newline at end of file + self.assertTrue(email_df.select("email").count() > 0) + +@pytest.mark.fast +class SparkNLPTestWordFilesSpec(unittest.TestCase): + + def setUp(self): + self.data = SparkContextForTest.data + self.word_file = f"file:///{os.getcwd()}/../src/test/resources/reader/doc/contains-pictures.docx" + + def runTest(self): + word_df = sparknlp.read().doc(self.word_file) + word_df.show() + + self.assertTrue(word_df.select("doc").count() > 0) \ No newline at end of file diff --git a/src/main/scala/com/johnsnowlabs/reader/ElementType.scala b/src/main/scala/com/johnsnowlabs/reader/ElementType.scala index f3167d10eb6867..0041f0ef3ca2df 100644 --- a/src/main/scala/com/johnsnowlabs/reader/ElementType.scala +++ b/src/main/scala/com/johnsnowlabs/reader/ElementType.scala @@ -25,5 +25,7 @@ object ElementType { val LINK = "Link" val TABLE = "Table" val ATTACHMENT = "Attachment" - + val LIST_ITEM = "ListItem" + val HEADER = "Header" + val FOOTER = "Footer" } diff --git a/src/main/scala/com/johnsnowlabs/reader/SparkNLPReader.scala b/src/main/scala/com/johnsnowlabs/reader/SparkNLPReader.scala index 68ecd40ba41c13..edc27f66b6424e 100644 --- a/src/main/scala/com/johnsnowlabs/reader/SparkNLPReader.scala +++ b/src/main/scala/com/johnsnowlabs/reader/SparkNLPReader.scala @@ -17,10 +17,9 @@ package com.johnsnowlabs.reader import org.apache.spark.sql.DataFrame -import java.util import scala.collection.JavaConverters._ -class SparkNLPReader(params: java.util.Map[String, String] = new util.HashMap()) { +class SparkNLPReader(params: java.util.Map[String, String] = new java.util.HashMap()) { /** Instantiates class to read HTML files. * @@ -156,4 +155,9 @@ class SparkNLPReader(params: java.util.Map[String, String] = new util.HashMap()) addAttachmentContent } + def doc(docPath: String): DataFrame = { + val wordReader = new WordReader() + wordReader.doc(docPath) + } + } diff --git a/src/main/scala/com/johnsnowlabs/reader/WordReader.scala b/src/main/scala/com/johnsnowlabs/reader/WordReader.scala new file mode 100644 index 00000000000000..208a88d4073c86 --- /dev/null +++ b/src/main/scala/com/johnsnowlabs/reader/WordReader.scala @@ -0,0 +1,178 @@ +/* + * Copyright 2017-2024 John Snow Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.johnsnowlabs.reader + +import com.johnsnowlabs.nlp.util.io.ResourceHelper +import com.johnsnowlabs.reader.util.DocParser.RichParagraph +import com.johnsnowlabs.reader.util.DocxParser +import com.johnsnowlabs.reader.util.DocxParser.RichXWPFParagraph +import org.apache.poi.hwpf.HWPFDocument +import org.apache.poi.xwpf.usermodel.{XWPFDocument, XWPFParagraph, XWPFTable} +import org.apache.spark.sql.DataFrame +import org.apache.spark.sql.functions.{col, udf} + +import java.io.{ByteArrayInputStream, IOException} +import scala.collection.JavaConverters._ +import scala.collection.mutable + +class WordReader extends Serializable { + + private val spark = ResourceHelper.spark + import spark.implicits._ + + def doc(filePath: String): DataFrame = { + if (ResourceHelper.validFile(filePath)) { + val binaryFilesRDD = spark.sparkContext.binaryFiles(filePath) + val byteArrayRDD = binaryFilesRDD.map { case (path, portableDataStream) => + val byteArray = portableDataStream.toArray() + (path, byteArray) + } + byteArrayRDD + .toDF("path", "content") + .withColumn("doc", parseWordUDF(col("content"))) + } else throw new IllegalArgumentException(s"Invalid filePath: $filePath") + } + + private val parseWordUDF = udf((data: Array[Byte]) => { + parseDoc(data) + }) + + // Constants for file type identification + private val ZipMagicNumberFirstByte: Byte = + 0x50.toByte // First byte of ZIP files, indicating .docx + private val ZipMagicNumberSecondByte: Byte = + 0x4b.toByte // Second byte of ZIP files, indicating .docx + private val OleMagicNumber: Array[Byte] = + Array(0xd0.toByte, 0xcf.toByte, 0x11.toByte, 0xe0.toByte) // Bytes indicating .doc + + private var pageBreak = 0 + + private def isDocxFile(content: Array[Byte]): Boolean = { + content.length > 1 && content(0) == ZipMagicNumberFirstByte && content( + 1) == ZipMagicNumberSecondByte + } + + private def isDocFile(content: Array[Byte]): Boolean = { + content.length >= 4 && content.slice(0, 4).sameElements(OleMagicNumber) + } + + private def parseDoc(content: Array[Byte]): Seq[HTMLElement] = { + pageBreak = 0 + val docInputStream = new ByteArrayInputStream(content) + try { + if (isDocxFile(content)) { + val document = new XWPFDocument(docInputStream) + val headers = DocxParser.extractHeaders(document).map { header => + HTMLElement(ElementType.HEADER, header, mutable.Map()) + } + val footers = DocxParser.extractFooters(document).map { footer => + HTMLElement(ElementType.FOOTER, footer, mutable.Map()) + } + val docElements = parseDocxToElements(document) + headers ++ docElements ++ footers + } else if (isDocFile(content)) { + val document = new HWPFDocument(docInputStream) + val docElements = parseDocToElements(document) + docElements + } else { + Seq(HTMLElement(ElementType.UNCATEGORIZED_TEXT, "Unknown file format", mutable.Map())) + } + } catch { + case e: IOException => + throw new IOException(s"Error e: ${e.getMessage}") + } finally { + docInputStream.close() + } + } + + private def parseDocxToElements(document: XWPFDocument): Seq[HTMLElement] = { + + val elements = document.getBodyElements.asScala.flatMap { + case paragraph: XWPFParagraph => + processParagraph(paragraph, document, "paragraph") + + case table: XWPFTable => + processTable(table, document) + + case _ => None + } + + elements + } + + private def processParagraph( + paragraph: XWPFParagraph, + document: XWPFDocument, + source: String): Option[HTMLElement] = { + val text = paragraph.getText.trim + if (text.isEmpty) None + else { + val metadata = mutable.Map[String, String]() + + if (paragraph.isCustomPageBreak) { + pageBreak += 1 + metadata += ("pageBreak" -> pageBreak.toString) + } + + if (paragraph.isSectionBreak) { + pageBreak += 1 + metadata += "pageBreak" -> pageBreak.toString + } + + val elementType = paragraph match { + case p if p.isTitle => ElementType.TITLE + case p if p.isListItem => ElementType.LIST_ITEM + case _ => if (source == "table") ElementType.TABLE else ElementType.NARRATIVE_TEXT + } + Some(HTMLElement(elementType, text, metadata)) + } + } + + private def processTable(table: XWPFTable, document: XWPFDocument): Seq[HTMLElement] = { + table.getRows.asScala.flatMap { row => + row.getTableCells.asScala.flatMap { cell => + cell.getParagraphs.asScala.flatMap { paragraph => + processParagraph(paragraph, document, "table") + } + } + } + } + + private def parseDocToElements(document: HWPFDocument): Seq[HTMLElement] = { + + val paragraphs = document.getRange + val elements = (0 until paragraphs.numParagraphs).flatMap { i => + val paragraph = paragraphs.getParagraph(i) + val text = paragraph.text.trim + if (text.isEmpty) None + else { + val metadata = mutable.Map[String, String]() + paragraph match { + case p if p.isInTable(paragraphs) => + val tableText = p.tableText(paragraphs).getOrElse("") + Some(HTMLElement(ElementType.TABLE, tableText, metadata)) + case p if p.isTitle => Some(HTMLElement(ElementType.TITLE, text, metadata)) + case p if p.isListItem => Some(HTMLElement(ElementType.LIST_ITEM, text, metadata)) + case _ => Some(HTMLElement(ElementType.NARRATIVE_TEXT, text, metadata)) + } + + } + } + + elements + } + +} diff --git a/src/main/scala/com/johnsnowlabs/reader/util/DocParser.scala b/src/main/scala/com/johnsnowlabs/reader/util/DocParser.scala new file mode 100644 index 00000000000000..10654819bb2890 --- /dev/null +++ b/src/main/scala/com/johnsnowlabs/reader/util/DocParser.scala @@ -0,0 +1,73 @@ +/* + * Copyright 2017-2024 John Snow Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.johnsnowlabs.reader.util + +import org.apache.poi.hwpf.usermodel.{Paragraph, Range, Table} + +import scala.util.Try + +object DocParser { + + implicit class RichParagraph(paragraph: Paragraph) { + + def isTitle: Boolean = { + + val text = paragraph.text.trim + val isUppercase = (text == text.toUpperCase) && !isListItem + (containsBoldText && containsCapitalizedWords) || (isUppercase && isCenterAligned) + } + + private def containsBoldText: Boolean = { + val characterRuns = (0 until paragraph.numCharacterRuns).map(paragraph.getCharacterRun) + characterRuns.exists(_.isBold) + } + + private def isCenterAligned: Boolean = { + paragraph.getJustification == 1 + } + + private def containsCapitalizedWords: Boolean = { + val words = paragraph.text.trim.split("\\s+") + words.forall(word => word.nonEmpty && word.head.isUpper) + } + + def isListItem: Boolean = { + val text = paragraph.text.trim + text.startsWith("•") || text.startsWith("–") || text.startsWith("*") || + paragraph.getIndentFromLeft > 0 + } + + def isInTable(range: Range): Boolean = { + Try(range.getTable(paragraph)).isSuccess + } + + def tableText(range: Range): Option[String] = { + Try { + val table = range.getTable(paragraph) + val rows = (0 until table.numRows).map(table.getRow) + val cellTexts = rows.flatMap(row => + (0 until row.numCells) + .flatMap { cellIndex => + val cell = row.getCell(cellIndex) + (0 until cell.numParagraphs).map(cell.getParagraph) + } + .map(_.text.trim)) + cellTexts.mkString(" | ") // Join cell texts with a separator + }.toOption + } + } + +} diff --git a/src/main/scala/com/johnsnowlabs/reader/util/DocxParser.scala b/src/main/scala/com/johnsnowlabs/reader/util/DocxParser.scala new file mode 100644 index 00000000000000..966e85f5c6749e --- /dev/null +++ b/src/main/scala/com/johnsnowlabs/reader/util/DocxParser.scala @@ -0,0 +1,136 @@ +/* + * Copyright 2017-2024 John Snow Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.johnsnowlabs.reader.util + +import org.apache.poi.xwpf.usermodel.{ParagraphAlignment, XWPFDocument, XWPFParagraph, XWPFRun} + +import scala.collection.JavaConverters._ + +object DocxParser { + + implicit class RichXWPFParagraph(paragraph: XWPFParagraph) { + + private def isListParagraph: Boolean = + paragraph.getStyle != null && paragraph.getStyle.startsWith("List") + + private def isNumberList: Boolean = { + val numId = paragraph.getNumID + numId != null && paragraph.getDocument.getNumbering.getNum(numId) != null + } + + private def isBulletPoint: Boolean = { + if (paragraph.getNumID == null) { + // Check for common bullet characters, indentation, or specific styling + val text = paragraph.getText.trim + text.startsWith("•") || text.startsWith("–") || text.startsWith("*") || + paragraph.getIndentationLeft > 0 || + paragraph.getRuns.toArray.exists { case run: XWPFRun => + run.getFontFamily == "Wingdings" + } + } else { + false + } + } + + def isListItem: Boolean = { + isListParagraph || isNumberList || isBulletPoint + } + + def isTitle: Boolean = { + (paragraph.getStyle != null && paragraph.getStyle.startsWith("Heading")) || + isBold && isCentered || + isBold && isUppercaseOrCapitalized + } + + def isBold: Boolean = paragraph.getRuns.toArray.exists { case run: XWPFRun => + run.isBold + } + + def isCentered: Boolean = { + val alignment = paragraph.getAlignment + alignment == ParagraphAlignment.CENTER || alignment == ParagraphAlignment.BOTH + } + + private def isUppercaseOrCapitalized: Boolean = { + val text = paragraph.getText.trim + text.nonEmpty && (text.forall(_.isUpper) || + text.split("\\s+").exists(word => word.headOption.exists(_.isUpper))) + } + + def isCustomPageBreak: Boolean = { + val ctp = paragraph.getCTP // Get the paragraph's XML representation + Option(ctp.getDomNode).exists { node => + val allNodes = getAllNodes(node) + allNodes.exists { child => + // Check for manual page break + (child.getNodeName == "w:br" && + Option(child.getAttributes).exists(attrs => + Option(attrs.getNamedItem("w:type")).exists(_.getNodeValue == "page"))) || + // Check for rendered page break + child.getNodeName == "w:lastRenderedPageBreak" + } + } + } + + // Helper function to traverse all child nodes recursively + private def getAllNodes(node: org.w3c.dom.Node): Seq[org.w3c.dom.Node] = { + val children = node.getChildNodes + (0 until children.getLength).flatMap { i => + val child = children.item(i) + Seq(child) ++ getAllNodes(child) + } + } + + def isSectionBreak: Boolean = { + val ctp = paragraph.getCTP + Option(ctp.getPPr).exists(_.isSetSectPr) + } + + } + + def extractHeaders(document: XWPFDocument): Seq[String] = { + val headerFooterPolicy = Option(document.getHeaderFooterPolicy) + headerFooterPolicy.toSeq.flatMap { policy => + Seq( + Option(policy.getDefaultHeader), + Option(policy.getFirstPageHeader), + Option(policy.getEvenPageHeader)).flatten + .flatMap { header => + header.getParagraphs.asScala.map { paragraph => + paragraph.getText.trim + } + } + .filter(_.nonEmpty) + } + } + + def extractFooters(document: XWPFDocument): Seq[String] = { + val headerFooterPolicy = Option(document.getHeaderFooterPolicy) + headerFooterPolicy.toSeq.flatMap { policy => + Seq( + Option(policy.getDefaultFooter), + Option(policy.getFirstPageFooter), + Option(policy.getEvenPageFooter)).flatten + .flatMap { footer => + footer.getParagraphs.asScala.map { paragraph => + paragraph.getText.trim + } + } + .filter(_.nonEmpty) + } + } + +} diff --git a/src/test/scala/com/johnsnowlabs/reader/WordReaderTest.scala b/src/test/scala/com/johnsnowlabs/reader/WordReaderTest.scala new file mode 100644 index 00000000000000..d98293cf595833 --- /dev/null +++ b/src/test/scala/com/johnsnowlabs/reader/WordReaderTest.scala @@ -0,0 +1,67 @@ +/* + * Copyright 2017-2024 John Snow Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.johnsnowlabs.reader + +import com.johnsnowlabs.nlp.util.io.ResourceHelper +import com.johnsnowlabs.tags.FastTest +import org.apache.spark.sql.functions.{array_contains, col, explode, map_keys} +import org.scalatest.flatspec.AnyFlatSpec + +class WordReaderTest extends AnyFlatSpec { + + private val spark = ResourceHelper.spark + val docDirectory = "src/test/resources/reader/doc" + + import spark.implicits._ + + "WordReader" should "read a directory of word files" taggedAs FastTest in { + val wordReader = new WordReader() + val wordDf = wordReader.doc(docDirectory) + wordDf.select("doc").show(false) + + assert(!wordDf.select(col("doc").getItem(0)).isEmpty) + } + + "WordReader" should "read a docx file with page breaks" taggedAs FastTest in { + val wordReader = new WordReader() + val wordDf = wordReader.doc(s"$docDirectory/page-breaks.docx") + wordDf.select("doc").show(false) + + val pageBreakCount = wordDf + .select(explode($"doc.metadata").as("metadata")) + .filter(array_contains(map_keys($"metadata"), "pageBreak")) + .count() + + assert(pageBreakCount == 5) + } + + "WordReader" should "read a docx file with tables" taggedAs FastTest in { + val wordReader = new WordReader() + val wordDf = wordReader.doc(s"$docDirectory/fake_table.docx") + wordDf.select("doc").show(false) + + assert(!wordDf.select(col("doc").getItem(0)).isEmpty) + } + + "WordReader" should "read a docx file with images on it" taggedAs FastTest in { + val wordReader = new WordReader() + val wordDf = wordReader.doc(s"$docDirectory/contains-pictures.docx") + wordDf.select("doc").show(false) + + assert(!wordDf.select(col("doc").getItem(0)).isEmpty) + } + +} From e2c63d6bca1cdd87e89830760a6fd4b7bfc013f8 Mon Sep 17 00:00:00 2001 From: Danilo Burbano Date: Tue, 10 Dec 2024 21:06:23 -0500 Subject: [PATCH 2/6] [SPARKNLP-1094] Adding test doc examples --- .../resources/reader/doc/contains-pictures.docx | Bin 0 -> 95087 bytes src/test/resources/reader/doc/fake_table.docx | Bin 0 -> 12392 bytes src/test/resources/reader/doc/page-breaks.docx | Bin 0 -> 14584 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 src/test/resources/reader/doc/contains-pictures.docx create mode 100755 src/test/resources/reader/doc/fake_table.docx create mode 100755 src/test/resources/reader/doc/page-breaks.docx diff --git a/src/test/resources/reader/doc/contains-pictures.docx b/src/test/resources/reader/doc/contains-pictures.docx new file mode 100755 index 0000000000000000000000000000000000000000..ee5cbede203d4554325c35db462fde9ae255dd6b GIT binary patch literal 95087 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

%+jP4AP__T4`QT$D$mbk;E`>!!&Iep-jPu0=`cP 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/reader/doc/fake_table.docx b/src/test/resources/reader/doc/fake_table.docx new file mode 100755 index 0000000000000000000000000000000000000000..663c52d36f6fc0d781ccc12315c7f87984659a7d GIT binary patch literal 12392 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 z�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 Date: Tue, 10 Dec 2024 21:55:54 -0500 Subject: [PATCH 3/6] [SPARKNLP-1094] Adding notebook example for Word files --- .../reader/SparkNLP_Email_Reader_Demo.ipynb | 552 ++++++++---------- .../reader/SparkNLP_HTML_Reader_Demo.ipynb | 8 +- .../reader/SparkNLP_Word_Reader_Demo.ipynb | 260 +++++++++ 3 files changed, 494 insertions(+), 326 deletions(-) create mode 100644 examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb diff --git a/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb b/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb index 6e13d6bfa7c9de..9a6ea733aa6cbc 100644 --- a/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb +++ b/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb @@ -1,334 +1,240 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "tzcU5p2gdak9" - }, - "source": [ - "# Introducing Email reader in SparkNLP\n", - "This notebook showcases the newly added `sparknlp.read().email()` method in Spark NLP that parses email content from both local file system and distributed file systems into a Spark DataFrame." - ] - }, - { - "cell_type": "code", - "source": [ - "from google.colab import drive\n", - "drive.mount('/content/drive')" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "xrvHhiTAdfGd", - "outputId": "07fb7294-33b3-4af0-f4ac-d87e43fd21b6" - }, - "execution_count": 1, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Mounted at /content/drive\n" - ] - } - ] - }, - { - "cell_type": "code", - "source": [ - "!cp drive/MyDrive/JSL/sparknlp/sparknlp.jar .\n", - "!cp drive/MyDrive/JSL/sparknlp/spark_nlp-5.5.1-py2.py3-none-any.whl ." - ], - "metadata": { - "id": "mjV3NcQ8eA52" - }, - "execution_count": 8, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "!pip install pyspark" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "pEmutNjReCgc", - "outputId": "32610063-174f-432b-be4a-6ab2ae9dd709" - }, - "execution_count": 3, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Requirement already satisfied: pyspark in /usr/local/lib/python3.10/dist-packages (3.5.3)\n", - "Requirement already satisfied: py4j==0.10.9.7 in /usr/local/lib/python3.10/dist-packages (from pyspark) (0.10.9.7)\n" - ] - } - ] - }, - { - "cell_type": "code", - "source": [ - "!pip install spark_nlp-5.5.1-py2.py3-none-any.whl" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "3qjPeDjvfCpA", - "outputId": "620c793f-5cb1-4a82-f687-53f3be348d9c" - }, - "execution_count": 9, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Processing ./spark_nlp-5.5.1-py2.py3-none-any.whl\n", - "Installing collected packages: spark-nlp\n", - "Successfully installed spark-nlp-5.5.1\n" - ] - } - ] - }, - { - "cell_type": "code", - "source": [ - "# import sparknlp\n", - "# # let's start Spark with Spark NLP\n", - "# spark = sparknlp.start()\n", - "\n", - "from pyspark.sql import SparkSession\n", - "\n", - "spark = SparkSession.builder \\\n", - " .appName(\"SparkNLP\") \\\n", - " .master(\"local[*]\") \\\n", - " .config(\"spark.driver.memory\", \"12G\") \\\n", - " .config(\"spark.serializer\", \"org.apache.spark.serializer.KryoSerializer\") \\\n", - " .config(\"spark.kryoserializer.buffer.max\", \"2000M\") \\\n", - " .config(\"spark.driver.maxResultSize\", \"0\") \\\n", - " .config(\"spark.jars\", \"./sparknlp.jar\") \\\n", - " .getOrCreate()\n", - "\n", - "\n", - "print(\"Apache Spark version: {}\".format(spark.version))" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "DczWop6QeE8F", - "outputId": "714b032f-e076-4aa3-8cf2-10eea6993c4d" - }, - "execution_count": 5, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Apache Spark version: 3.5.3\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "RFOFhaEedalB" - }, - "source": [ - "## Setup and Initialization\n", - "Let's keep in mind a few things before we start 😊\n", - "\n", - "Support for reading email files was introduced in Spark NLP 5.5.2. Please make sure you have upgraded to the latest Spark NLP release.\n", - "\n", - "For local files example we will download a couple of email files from Spark NLP Github repo:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ya8qZe00dalC", - "outputId": "a9916407-f76d-4c59-fdad-ea17ca0a4326" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "mkdir: cannot create directory ‘email-files’: File exists\n", - "--2024-11-13 21:01:15-- https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1093-Adding-support-to-read-Email-files/src/test/resources/reader/email/email-text-attachments.eml\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 3175 (3.1K) [text/plain]\n", - "Saving to: ‘email-files/email-text-attachments.eml’\n", - "\n", - "email-text-attachme 100%[===================>] 3.10K --.-KB/s in 0s \n", - "\n", - "2024-11-13 21:01:15 (29.9 MB/s) - ‘email-files/email-text-attachments.eml’ saved [3175/3175]\n", - "\n", - "--2024-11-13 21:01:15-- https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1093-Adding-support-to-read-Email-files/src/test/resources/reader/email/test-several-attachments.eml\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 1324361 (1.3M) [text/plain]\n", - "Saving to: ‘email-files/test-several-attachments.eml’\n", - "\n", - "test-several-attach 100%[===================>] 1.26M --.-KB/s in 0.05s \n", - "\n", - "2024-11-13 21:01:16 (26.7 MB/s) - ‘email-files/test-several-attachments.eml’ saved [1324361/1324361]\n", - "\n" - ] - } - ], - "source": [ - "!mkdir email-files\n", - "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1093-Adding-support-to-read-Email-files/src/test/resources/reader/email/email-text-attachments.eml -P email-files\n", - "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1093-Adding-support-to-read-Email-files/src/test/resources/reader/email/test-several-attachments.eml -P email-files" - ] - }, - { - "cell_type": "code", - "source": [ - "!ls -lh ./email-files" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "3xgGItNbU2DZ", - "outputId": "12f8a7be-f9b4-49ce-a9ab-222142f28293" - }, - "execution_count": 18, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "total 1.3M\n", - "-rw-r--r-- 1 root root 3.2K Nov 13 21:01 email-text-attachments.eml\n", - "-rw-r--r-- 1 root root 1.3M Nov 13 21:01 test-several-attachments.eml\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "EoFI66NAdalE" - }, - "source": [ - "## Parsing Email from Local Files\n", - "Use the `email()` method to parse email content from local directories." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![JohnSnowLabs](https://sparknlp.org/assets/images/logo.png)\n", + "\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/JohnSnowLabs/spark-nlp/blob/master/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tzcU5p2gdak9" + }, + "source": [ + "# Introducing Email reader in SparkNLP\n", + "This notebook showcases the newly added `sparknlp.read().email()` method in Spark NLP that parses email content from both local file system and distributed file systems into a Spark DataFrame." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RFOFhaEedalB" + }, + "source": [ + "## Setup and Initialization\n", + "Let's keep in mind a few things before we start 😊\n", + "\n", + "Support for reading email files was introduced in Spark NLP 5.5.2. Please make sure you have upgraded to the latest Spark NLP release." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Let's install and setup Spark NLP in Google Colab\n", + "- This part is pretty easy via our simple script" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! wget -q http://setup.johnsnowlabs.com/colab.sh -O - | bash" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For local files example we will download a couple of email files from Spark NLP Github repo:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "ya8qZe00dalC", + "outputId": "a9916407-f76d-4c59-fdad-ea17ca0a4326" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "bAkMjJ1vdalE", - "outputId": "4b360b6c-5049-4f10-bb52-60e0e0e52e52" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Warning::Spark Session already created, some configs may not take.\n", - "+--------------------+\n", - "| email|\n", - "+--------------------+\n", - "|[{Title, Email Te...|\n", - "|[{Title, Test Sev...|\n", - "+--------------------+\n", - "\n" - ] - } - ], - "source": [ - "import sparknlp\n", - "email_df = sparknlp.read().email(\"./email-files\")\n", - "\n", - "email_df.select(\"email\").show()" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "mkdir: cannot create directory ‘email-files’: File exists\n", + "--2024-11-13 21:01:15-- https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1093-Adding-support-to-read-Email-files/src/test/resources/reader/email/email-text-attachments.eml\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 3175 (3.1K) [text/plain]\n", + "Saving to: ‘email-files/email-text-attachments.eml’\n", + "\n", + "email-text-attachme 100%[===================>] 3.10K --.-KB/s in 0s \n", + "\n", + "2024-11-13 21:01:15 (29.9 MB/s) - ‘email-files/email-text-attachments.eml’ saved [3175/3175]\n", + "\n", + "--2024-11-13 21:01:15-- https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1093-Adding-support-to-read-Email-files/src/test/resources/reader/email/test-several-attachments.eml\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 1324361 (1.3M) [text/plain]\n", + "Saving to: ‘email-files/test-several-attachments.eml’\n", + "\n", + "test-several-attach 100%[===================>] 1.26M --.-KB/s in 0.05s \n", + "\n", + "2024-11-13 21:01:16 (26.7 MB/s) - ‘email-files/test-several-attachments.eml’ saved [1324361/1324361]\n", + "\n" + ] + } + ], + "source": [ + "!mkdir email-files\n", + "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/master/src/test/resources/reader/email/email-text-attachments.eml -P email-files\n", + "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/master/src/test/resources/reader/email/test-several-attachments.eml -P email-files" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "3xgGItNbU2DZ", + "outputId": "12f8a7be-f9b4-49ce-a9ab-222142f28293" + }, + "outputs": [ { - "cell_type": "code", - "source": [ - "email_df.printSchema()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "7CMPPubFTeHj", - "outputId": "48ee68cf-0f7f-408a-a855-2fd2eb2e8bd1" - }, - "execution_count": 21, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "root\n", - " |-- path: string (nullable = true)\n", - " |-- content: binary (nullable = true)\n", - " |-- email: array (nullable = true)\n", - " | |-- element: struct (containsNull = true)\n", - " | | |-- elementType: string (nullable = true)\n", - " | | |-- content: string (nullable = true)\n", - " | | |-- metadata: map (nullable = true)\n", - " | | | |-- key: string\n", - " | | | |-- value: string (valueContainsNull = true)\n", - "\n" - ] - } - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "total 1.3M\n", + "-rw-r--r-- 1 root root 3.2K Nov 13 21:01 email-text-attachments.eml\n", + "-rw-r--r-- 1 root root 1.3M Nov 13 21:01 test-several-attachments.eml\n" + ] + } + ], + "source": [ + "!ls -lh ./email-files" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EoFI66NAdalE" + }, + "source": [ + "## Parsing Email from Local Files\n", + "Use the `email()` method to parse email content from local directories." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "bAkMjJ1vdalE", + "outputId": "4b360b6c-5049-4f10-bb52-60e0e0e52e52" + }, + "outputs": [ { - "cell_type": "markdown", - "source": [ - "You can also use DFS like Databricks `dbfs://` or HDFS directories `hdfs://`" - ], - "metadata": { - "id": "Qooecm9VTeus" - } + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning::Spark Session already created, some configs may not take.\n", + "+--------------------+\n", + "| email|\n", + "+--------------------+\n", + "|[{Title, Email Te...|\n", + "|[{Title, Test Sev...|\n", + "+--------------------+\n", + "\n" + ] } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - }, + ], + "source": [ + "import sparknlp\n", + "email_df = sparknlp.read().email(\"./email-files\")\n", + "\n", + "email_df.select(\"email\").show()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { "colab": { - "provenance": [] + "base_uri": "https://localhost:8080/" + }, + "id": "7CMPPubFTeHj", + "outputId": "48ee68cf-0f7f-408a-a855-2fd2eb2e8bd1" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "root\n", + " |-- path: string (nullable = true)\n", + " |-- content: binary (nullable = true)\n", + " |-- email: array (nullable = true)\n", + " | |-- element: struct (containsNull = true)\n", + " | | |-- elementType: string (nullable = true)\n", + " | | |-- content: string (nullable = true)\n", + " | | |-- metadata: map (nullable = true)\n", + " | | | |-- key: string\n", + " | | | |-- value: string (valueContainsNull = true)\n", + "\n" + ] } + ], + "source": [ + "email_df.printSchema()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qooecm9VTeus" + }, + "source": [ + "You can also use DFS like Databricks `dbfs://` or HDFS directories `hdfs://`" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb b/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb index 7fde42b1bf6ca1..03b62ab90ec3c6 100644 --- a/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb +++ b/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb @@ -44,8 +44,10 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "! wget -q http://setup.johnsnowlabs.com/colab.sh -O - | bash" ] @@ -101,8 +103,8 @@ ], "source": [ "!mkdir html-files\n", - "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1089-Support-more-file-types-in-SparkNLP/src/test/resources/reader/html/example-10k.html -P html-files\n", - "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1089-Support-more-file-types-in-SparkNLP/src/test/resources/reader/html/fake-html.html -P html-files" + "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/master/src/test/resources/reader/html/example-10k.html -P html-files\n", + "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/master/src/test/resources/reader/html/fake-html.html -P html-files" ] }, { diff --git a/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb b/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb new file mode 100644 index 00000000000000..d2179aa8db062b --- /dev/null +++ b/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![JohnSnowLabs](https://sparknlp.org/assets/images/logo.png)\n", + "\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/JohnSnowLabs/spark-nlp/blob/master/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tzcU5p2gdak9" + }, + "source": [ + "# Introducing Word reader in SparkNLP\n", + "This notebook showcases the newly added `sparknlp.read().doc()` method in Spark NLP that parses Word documents content from both local and distributed file systems into a Spark DataFrame." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RFOFhaEedalB" + }, + "source": [ + "## Setup and Initialization\n", + "Let's keep in mind a few things before we start 😊\n", + "\n", + "Support for reading Word files was introduced in Spark NLP 5.5.2. Please make sure you have upgraded to the latest Spark NLP release." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Let's install and setup Spark NLP in Google Colab\n", + "- This part is pretty easy via our simple script" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! wget -q http://setup.johnsnowlabs.com/colab.sh -O - | bash" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For local files example we will download a couple of Word files from Spark NLP Github repo:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ya8qZe00dalC", + "outputId": "f6800bce-c101-47e3-8030-cf1a0b758183" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2024-12-11 02:43:35-- https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1094-Adding-support-to-read-Word-files-v2/src/test/resources/reader/doc/contains-pictures.docx\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.108.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 95087 (93K) [application/octet-stream]\n", + "Saving to: ‘word-files/contains-pictures.docx’\n", + "\n", + "contains-pictures.d 100%[===================>] 92.86K --.-KB/s in 0.04s \n", + "\n", + "2024-12-11 02:43:35 (2.47 MB/s) - ‘word-files/contains-pictures.docx’ saved [95087/95087]\n", + "\n", + "--2024-12-11 02:43:36-- https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/feature/SPARKNLP-1094-Adding-support-to-read-Word-files-v2/src/test/resources/reader/doc/fake_table.docx\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.111.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 12392 (12K) [application/octet-stream]\n", + "Saving to: ‘word-files/fake_table.docx’\n", + "\n", + "fake_table.docx 100%[===================>] 12.10K --.-KB/s in 0s \n", + "\n", + "2024-12-11 02:43:36 (24.7 MB/s) - ‘word-files/fake_table.docx’ saved [12392/12392]\n", + "\n" + ] + } + ], + "source": [ + "!mkdir word-files\n", + "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/master/src/test/resources/reader/doc/contains-pictures.docx -P word-files\n", + "!wget https://raw.githubusercontent.com/JohnSnowLabs/spark-nlp/master/src/test/resources/reader/doc/fake_table.docx -P word-files" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "oZLpFt7qcWoC", + "outputId": "6e5ce0b8-383a-481c-9b7b-d4250d385f25" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total 112K\n", + "-rw-r--r-- 1 root root 93K Dec 11 02:43 contains-pictures.docx\n", + "-rw-r--r-- 1 root root 13K Dec 11 02:43 fake_table.docx\n" + ] + } + ], + "source": [ + "!ls -lh ./word-files" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TII6UaLqcZw4" + }, + "source": [ + "## Parsing Word document from Local Files\n", + "Use the `doc()` method to parse email content from local directories." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "_3GKYbmScehR", + "outputId": "24941880-c772-4b4e-dd0d-349fe8ea31c9" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning::Spark Session already created, some configs may not take.\n" + ] + } + ], + "source": [ + "import sparknlp\n", + "\n", + "doc_df = sparknlp.read().doc(\"./word-files\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "eKOYqIigmlmh", + "outputId": "1a3ec3b7-b49d-420b-cdaf-e4682b4f66e1" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "+--------------------+\n", + "| doc|\n", + "+--------------------+\n", + "|[{Table, Header C...|\n", + "|[{Header, An inli...|\n", + "+--------------------+\n", + "\n" + ] + } + ], + "source": [ + "doc_df.select(\"doc\").show()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "IoC1eqPPcmqN", + "outputId": "b994396c-b670-49af-8bb9-b5e6ff44e8fe" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "root\n", + " |-- path: string (nullable = true)\n", + " |-- content: binary (nullable = true)\n", + " |-- doc: array (nullable = true)\n", + " | |-- element: struct (containsNull = true)\n", + " | | |-- elementType: string (nullable = true)\n", + " | | |-- content: string (nullable = true)\n", + " | | |-- metadata: map (nullable = true)\n", + " | | | |-- key: string\n", + " | | | |-- value: string (valueContainsNull = true)\n", + "\n" + ] + } + ], + "source": [ + "doc_df.printSchema()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GtzqE1P8cpXE" + }, + "source": [ + "You can also use DFS like Databricks `dbfs://` or HDFS directories `hdfs://`" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} From 3da2e46f832fa847e07b9373564f9132840a3a28 Mon Sep 17 00:00:00 2001 From: Danilo Burbano Date: Fri, 13 Dec 2024 18:52:17 -0500 Subject: [PATCH 4/6] [SPARKNLP-1094] Adding latest jakarta mail dependencies --- build.sbt | 1 + project/Dependencies.scala | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index d3913301c73a22..b90d5418243db4 100644 --- a/build.sbt +++ b/build.sbt @@ -159,6 +159,7 @@ lazy val utilDependencies = Seq( azureStorage, jsoup, jakartaMail, + angusMail, poiDocx exclude ("org.apache.logging.log4j", "log4j-api"), scratchpad diff --git a/project/Dependencies.scala b/project/Dependencies.scala index abca4bc5fd08a2..fae6267df57f21 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -137,8 +137,10 @@ object Dependencies { val jsoupVersion = "1.18.2" val jsoup = "org.jsoup" % "jsoup" % jsoupVersion - val jakartaMailVersion = "2.0.1" - val jakartaMail = "com.sun.mail" % "jakarta.mail" % "2.0.1" + val jakartaMailVersion = "2.1.3" + val jakartaMail = "jakarta.mail" % "jakarta.mail-api" % jakartaMailVersion + val angusMailVersion = "2.0.3" + val angusMail = "org.eclipse.angus" % "angus-mail" % angusMailVersion val poiVersion = "4.1.2" val poiDocx = "org.apache.poi" % "poi-ooxml" % poiVersion From d9889318566b569b93a477272308da6428f9a757 Mon Sep 17 00:00:00 2001 From: Danilo Burbano Date: Fri, 13 Dec 2024 19:16:30 -0500 Subject: [PATCH 5/6] [SPARKNLP-1094] Updating notebooks documentation --- .../reader/SparkNLP_Email_Reader_Demo.ipynb | 24 ++++++++++++++++++- .../reader/SparkNLP_HTML_Reader_Demo.ipynb | 10 ++++++++ .../reader/SparkNLP_Word_Reader_Demo.ipynb | 5 +++- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb b/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb index 9a6ea733aa6cbc..1e35592f81f748 100644 --- a/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb +++ b/examples/python/reader/SparkNLP_Email_Reader_Demo.ipynb @@ -48,6 +48,25 @@ "! wget -q http://setup.johnsnowlabs.com/colab.sh -O - | bash" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Additional Configuration for Databricks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When running on Databricks, it is necessary to include the following Spark configurations to avoid dependency conflicts:\n", + "\n", + "- `spark.driver.userClassPathFirst true`\n", + "- `spark.executor.userClassPathFirst true`\n", + "\n", + "These configurations are required because the Databricks runtime environment includes a bundled version of the `com.sun.mail:jakarta.mail` library, which conflicts with `jakarta.activation`. By setting these properties, the application ensures that the user-provided libraries take precedence over those bundled in the Databricks environment, resolving the dependency conflict." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -209,7 +228,10 @@ "id": "Qooecm9VTeus" }, "source": [ - "You can also use DFS like Databricks `dbfs://` or HDFS directories `hdfs://`" + "You can also use DFS file systems like:\n", + "- Databricks: `dbfs://`\n", + "- HDFS: `hdfs://`\n", + "- Microsoft Fabric OneLake: `abfss://`" ] } ], diff --git a/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb b/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb index 03b62ab90ec3c6..99782a9e04683c 100644 --- a/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb +++ b/examples/python/reader/SparkNLP_HTML_Reader_Demo.ipynb @@ -150,6 +150,16 @@ "html_df.show()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also use DFS file systems like:\n", + "- Databricks: `dbfs://`\n", + "- HDFS: `hdfs://`\n", + "- Microsoft Fabric OneLake: `abfss://`" + ] + }, { "cell_type": "markdown", "metadata": { diff --git a/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb b/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb index d2179aa8db062b..15f4f99a2ca33a 100644 --- a/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb +++ b/examples/python/reader/SparkNLP_Word_Reader_Demo.ipynb @@ -229,7 +229,10 @@ "id": "GtzqE1P8cpXE" }, "source": [ - "You can also use DFS like Databricks `dbfs://` or HDFS directories `hdfs://`" + "You can also use DFS file systems like:\n", + "- Databricks: `dbfs://`\n", + "- HDFS: `hdfs://`\n", + "- Microsoft Fabric OneLake: `abfss://`" ] } ], From db308a525df2f34d35f4e167fbd8f9c7ae311780 Mon Sep 17 00:00:00 2001 From: Danilo Burbano Date: Sun, 15 Dec 2024 08:55:39 -0500 Subject: [PATCH 6/6] [SPARKNLP-1094] Updating Databricks documentation --- docs/en/advanced_settings.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/en/advanced_settings.md b/docs/en/advanced_settings.md index f21bf11d56a93a..47e4a43e7843d6 100644 --- a/docs/en/advanced_settings.md +++ b/docs/en/advanced_settings.md @@ -96,6 +96,16 @@ spark.jsl.settings.annotator.log_folder dbfs:/PATH_TO_LOGS NOTE: If this is an existing cluster, after adding new configs or changing existing properties you need to restart it. +#### Additional Configuration for Databricks +When running Email Reader feature `sparknlp.read().email("./email-files")` on Databricks, it is necessary to include the following Spark configurations to avoid dependency conflicts: + +```bash +spark.driver.userClassPathFirst true +spark.executor.userClassPathFirst true +``` +These configurations are required because the Databricks runtime environment includes a bundled version of the `com.sun.mail:jakarta.mail` library, which conflicts with `jakarta.activation`. +By setting these properties, the application ensures that the user-provided libraries take precedence over those bundled in the Databricks environment, resolving the dependency conflict. +

### S3 Integration