11import shutil
22import tempfile
33from datetime import datetime
4- from typing import TYPE_CHECKING , List , Union , cast
4+ from typing import TYPE_CHECKING , List , Union
55from urllib .parse import urlparse
66
77from feast .config import Config
2323 CONFIG_SPARK_LAUNCHER ,
2424 CONFIG_SPARK_STANDALONE_MASTER ,
2525)
26- from feast .data_source import BigQuerySource , DataSource , FileSource
26+ from feast .data_source import BigQuerySource , DataSource , FileSource , KafkaSource
2727from feast .feature_table import FeatureTable
2828from feast .pyspark .abc import (
29- IngestionJob ,
30- IngestionJobParameters ,
29+ BatchIngestionJob ,
30+ BatchIngestionJobParameters ,
3131 JobLauncher ,
3232 RetrievalJob ,
3333 RetrievalJobParameters ,
34+ StreamIngestionJob ,
35+ StreamIngestionJobParameters ,
3436)
3537from feast .staging .storage_client import get_staging_client
3638from feast .value_type import ValueType
@@ -85,10 +87,7 @@ def resolve_launcher(config: Config) -> JobLauncher:
8587 return _launchers [config .get (CONFIG_SPARK_LAUNCHER )](config )
8688
8789
88- _SOURCES = {
89- FileSource : ("file" , "file_options" ),
90- BigQuerySource : ("bq" , "bigquery_options" ),
91- }
90+ _SOURCES = {FileSource : "file" , BigQuerySource : "bq" , KafkaSource : "kafka" }
9291
9392
9493def _source_to_argument (source : DataSource ):
@@ -99,16 +98,19 @@ def _source_to_argument(source: DataSource):
9998 "date_partition_column" : source .date_partition_column ,
10099 }
101100
102- kind , option_field = _SOURCES [type (source )]
101+ kind = _SOURCES [type (source )]
103102 properties = {** common_properties }
104- if type (source ) == FileSource :
105- file_source = cast (FileSource , source )
106- properties ["path" ] = file_source .file_options .file_url
107- properties ["format" ] = str (file_source .file_options .file_format )
103+ if isinstance (source , FileSource ):
104+ properties ["path" ] = source .file_options .file_url
105+ properties ["format" ] = str (source .file_options .file_format )
106+ return {kind : properties }
107+ if isinstance (source , BigQuerySource ):
108+ properties ["table_ref" ] = source .bigquery_options .table_ref
108109 return {kind : properties }
109- if type (source ) == BigQuerySource :
110- bq_source = cast (BigQuerySource , source )
111- properties ["table_ref" ] = bq_source .bigquery_options .table_ref
110+ if isinstance (source , KafkaSource ):
111+ properties ["topic" ] = source .kafka_options .topic
112+ properties ["classpath" ] = source .kafka_options .class_path
113+ properties ["bootstrap_servers" ] = source .kafka_options .bootstrap_servers
112114 return {kind : properties }
113115 raise NotImplementedError (f"Unsupported Datasource: { type (source )} " )
114116
@@ -194,13 +196,13 @@ def _download_jar(remote_jar: str) -> str:
194196
195197def start_offline_to_online_ingestion (
196198 feature_table : FeatureTable , start : datetime , end : datetime , client : "Client"
197- ) -> IngestionJob :
199+ ) -> BatchIngestionJob :
198200
199201 launcher = resolve_launcher (client ._config )
200202 local_jar_path = _download_jar (client ._config .get (CONFIG_SPARK_INGESTION_JOB_JAR ))
201203
202204 return launcher .offline_to_online_ingestion (
203- IngestionJobParameters (
205+ BatchIngestionJobParameters (
204206 jar = local_jar_path ,
205207 source = _source_to_argument (feature_table .batch_source ),
206208 feature_table = _feature_table_to_argument (client , feature_table ),
@@ -213,6 +215,26 @@ def start_offline_to_online_ingestion(
213215 )
214216
215217
218+ def start_stream_to_online_ingestion (
219+ feature_table : FeatureTable , extra_jars : List [str ], client : "Client"
220+ ) -> StreamIngestionJob :
221+
222+ launcher = resolve_launcher (client ._config )
223+ local_jar_path = _download_jar (client ._config .get (CONFIG_SPARK_INGESTION_JOB_JAR ))
224+
225+ return launcher .start_stream_to_online_ingestion (
226+ StreamIngestionJobParameters (
227+ jar = local_jar_path ,
228+ extra_jars = extra_jars ,
229+ source = _source_to_argument (feature_table .stream_source ),
230+ feature_table = _feature_table_to_argument (client , feature_table ),
231+ redis_host = client ._config .get (CONFIG_REDIS_HOST ),
232+ redis_port = client ._config .getint (CONFIG_REDIS_PORT ),
233+ redis_ssl = client ._config .getboolean (CONFIG_REDIS_SSL ),
234+ )
235+ )
236+
237+
216238def stage_dataframe (
217239 df , event_timestamp_column : str , created_timestamp_column : str , client : "Client"
218240) -> FileSource :
0 commit comments