Remove Spark and the JVM from the CLI - #1478
Merged
Merged
Conversation
Nothing the CLI can reach needs PySpark any more, so no install of it needs Java. The remaining Spark server types (`dataframe`, Spark-mode `databricks`) run against a session the caller passes to the Python library, which a CLI container cannot supply, so PySpark is left to the caller who already has it. - Kafka is read with confluent-kafka, decoded in Python (fastavro for Avro), and checked in DuckDB. Adds DATACONTRACT_KAFKA_MAX_MESSAGES and DATACONTRACT_KAFKA_TIMEOUT, since messages are now held in memory. - The Spark exporters build their own type tree instead of pyspark objects. They only ever rendered it as source text; `to_spark_dict()` still returns real schemas, through the one function that imports pyspark. - `import unity` parses Spark's type JSON directly, so struct and array columns keep resolving into nested properties without pyspark installed. - The `kafka`, `databricks`, and `dataframe` extras no longer pin pyspark, so neither does `all`. `databricks-runtime` becomes an alias of `databricks`. - The tests that built a SparkSession are gone, along with the JDK setup in CI and the Java sections in the contributor docs. - The Docker image drops its JRE and moves to the shell-less base image: 2.47 GB to 1.28 GB.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nothing the CLI can reach needs PySpark any more, so no install of it needs Java.
datacontract-cli[all]resolves without pyspark, and the Docker image ships no JRE.The remaining Spark server types (
dataframe, Spark-modedatabricks) run against a session the caller passes toDataContract(spark=...), which a CLI container cannot supply. PySpark is therefore left to the caller, who cannot have built that session without it, and declaring it was only a way for pip to shadow the build a Databricks Runtime or EMR cluster provides.Kafka without Spark
spark-sql-kafka-0-10did the consuming,from_avro/from_jsonthe decoding, and checks ran throughibis.pysparkagainst a temp view. None of that needed a cluster — a CLI run is single-process either way — while pyspark pulled ~320 JARs and a JDK into every install.The topic is now consumed with confluent-kafka, decoded in Python (fastavro for Avro), and loaded into DuckDB, which the check engine already queries for every file-based source.
Two behaviours change deliberately, both noted in the changelog:
Because messages are held in memory rather than aggregated across Spark partitions,
DATACONTRACT_KAFKA_MAX_MESSAGESandDATACONTRACT_KAFKA_TIMEOUTare added. A truncated read says so in the run output.Exporters without pyspark
spark_exporterbuilt realpyspark.sql.typesobjects and walked them back into source text. The objects were never used as objects, so the mapping now produces its own type tree and renders from that.to_spark_dict()still returns real schemas via the single function that imports pyspark.This fixes
datacontract export sparkanddatacontract export great-expectations --engine spark, which failed with aModuleNotFoundErroron a base install since neither is behind a pyspark-carrying extra.to_spark_schema(),to_struct_type(),to_struct_field()andto_spark_data_type()now returnSparkDataTyperather than pyspark objects.to_spark_dict()is unchanged;to_pyspark_schema()is new for callers wanting a realStructType.import unity
StructField.fromJsonwas only a JSON parser, sodatacontract/imports/spark_type_json.pyreads the format directly. Verified against pyspark itself:simple_string()matchesDataType.simpleString()on all 20 type shapes tested, and the ODCS logical types match the existing mapping on 18 of 20 — the two differences aretinyintandchar(5), which make the pyspark path raiseAttributeErroron PySpark 3.5 because it falls through to aVariantTypebranch that does not exist before 4.0.The same class of bug in
to_pyspark()is now guarded with a message naming the installed version and the way around it, rather than a bareAttributeError.Tests and CI
The tests that built a SparkSession are removed:
test_test_dataframe.py, and the session-based cases oftest_import_spark.py. Two tests in the latter never touched Spark and moved totest_export_sodacl.py, where they belong.This leaves the
dataframeserver type andimport sparkwithout test coverage. Both still ship and still work; nothing verifies that. Worth a deliberate decision rather than discovering it later.The JDK setup is gone from both CI jobs, and the Java sections from
README.md,AGENTS.mdandcontributing.md.test_test_delta.pyandtest_export_spark.pywere listed there as needing Java and never did.Verification
The full suite runs with a meta-path hook that makes every
pysparkimport raise: 1805 passed, 21 skipped. The four Kafka testcontainer tests pass unchanged, and they no longer need theskipif(is_xdist_worker)guard that Spark's Java client required — 11s under-n 4, down from 49s serially.Image sizes are measured, by building
mainand this branch: 2.47 GB to 1.28 GB. The built image was smoke-tested with--versionandexport spark.