11import os
22import uuid
33from datetime import datetime
4+ from typing import Dict , List , cast
5+ from urllib .parse import urlparse
6+
7+ from google .api_core .operation import Operation
8+ from google .cloud import dataproc_v1 , storage
9+ from google .cloud .dataproc_v1 import Job as DataprocJob
10+ from google .cloud .dataproc_v1 import JobStatus
411
512from feast .pyspark .abc import (
13+ IngestionJob ,
14+ IngestionJobParameters ,
15+ JobLauncher ,
616 RetrievalJob ,
17+ RetrievalJobParameters ,
718 SparkJobFailure ,
8- JobLauncher ,
19+ SparkJobParameters ,
920 SparkJobStatus ,
10- SparkJob ,
11- IngestionJob ,
1221)
13- from google .api_core .operation import Operation
14- from google .cloud import dataproc_v1
15- from google .cloud import storage
16-
17- from typing import Dict , List , cast
18- from urllib .parse import urlparse
1922
20- from google .cloud .dataproc_v1 import Job as DataprocJob , JobStatus
2123
22-
23- class DataprocSparkJob (SparkJob ):
24- def __init__ (self , ** kwargs ):
25- super ().__init__ (** kwargs )
26- self ._operation = None # type: Operation
27-
28- def set_operation (self , operation : Operation ):
24+ class DataprocJobMixin :
25+ def __init__ (self , operation : Operation ):
2926 """
3027 :param operation: (google.api.core.operation.Operation): A Future for the spark job result,
3128 returned by the dataproc client.
@@ -47,19 +44,19 @@ def get_status(self) -> SparkJobStatus:
4744 return SparkJobStatus .FAILED
4845
4946
50- class DataprocRetrievalJob (RetrievalJob , DataprocSparkJob ):
47+ class DataprocRetrievalJob (DataprocJobMixin , RetrievalJob ):
5148 """
5249 Historical feature retrieval job result for a Dataproc cluster
5350 """
5451
55- def __init__ (self , output_file_uri , ** kwargs ):
52+ def __init__ (self , operation : Operation , output_file_uri : str ):
5653 """
5754 This is the returned historical feature retrieval job result for DataprocClusterLauncher.
5855
5956 Args:
6057 output_file_uri (str): Uri to the historical feature retrieval job output file.
6158 """
62- super ().__init__ (** kwargs )
59+ super ().__init__ (operation )
6360 self ._output_file_uri = output_file_uri
6461
6562 def get_output_file_uri (self , timeout_sec = None ):
@@ -70,18 +67,10 @@ def get_output_file_uri(self, timeout_sec=None):
7067 return self ._output_file_uri
7168
7269
73- class DataprocIngestionJob (IngestionJob , DataprocSparkJob ):
74- def __init__ (
75- self ,
76- feature_table : Dict ,
77- source : Dict ,
78- start : datetime ,
79- end : datetime ,
80- jar : str ,
81- ):
82- super ().__init__ (
83- feature_table = feature_table , source = source , start = start , end = end , jar = jar
84- )
70+ class DataprocIngestionJob (DataprocJobMixin , IngestionJob ):
71+ """
72+ Ingestion job result for a Dataproc cluster
73+ """
8574
8675
8776class DataprocClusterLauncher (JobLauncher ):
@@ -135,26 +124,24 @@ def _stage_files(self, pyspark_script: str, job_id: str) -> str:
135124
136125 return f"gs://{ self .staging_bucket } /{ blob_path } "
137126
138- def dataproc_submit (self , job : DataprocSparkJob ) -> Operation :
127+ def dataproc_submit (self , job_params : SparkJobParameters ) -> Operation :
139128 local_job_id = str (uuid .uuid4 ())
140- pyspark_gcs = self ._stage_files (job .get_main_file_path (), local_job_id )
129+ pyspark_gcs = self ._stage_files (job_params .get_main_file_path (), local_job_id )
141130 job_config = {
142131 "reference" : {"job_id" : local_job_id },
143132 "placement" : {"cluster_name" : self .cluster_name },
144133 "pyspark_job" : {
145134 "main_python_file_uri" : pyspark_gcs ,
146- "args" : job .get_arguments (),
135+ "args" : job_params .get_arguments (),
147136 },
148137 }
149- operation = self .job_client .submit_job_as_operation (
138+ return self .job_client .submit_job_as_operation (
150139 request = {
151140 "project_id" : self .project_id ,
152141 "region" : self .region ,
153142 "job" : job_config ,
154143 }
155144 )
156- job .set_operation (operation )
157- return operation
158145
159146 def historical_feature_retrieval (
160147 self ,
@@ -164,15 +151,16 @@ def historical_feature_retrieval(
164151 destination_conf : Dict ,
165152 ** kwargs ,
166153 ) -> RetrievalJob :
167- job = DataprocRetrievalJob (
168- output_file_uri = destination_conf ["path" ],
154+ job_params = RetrievalJobParameters (
169155 feature_tables = feature_tables_conf ,
170156 feature_tables_sources = feature_tables_sources_conf ,
171157 entity_source = entity_source_conf ,
172158 destination = destination_conf ,
173159 )
174- self .dataproc_submit (job )
175- return job
160+
161+ return DataprocRetrievalJob (
162+ self .dataproc_submit (job_params ), destination_conf ["path" ]
163+ )
176164
177165 def offline_to_online_ingestion (
178166 self ,
@@ -182,12 +170,11 @@ def offline_to_online_ingestion(
182170 start : datetime ,
183171 end : datetime ,
184172 ) -> IngestionJob :
185- job = DataprocIngestionJob (
173+ job_params = IngestionJobParameters (
186174 feature_table = feature_table_conf ,
187175 source = source_conf ,
188176 start = start ,
189177 end = end ,
190178 jar = jar_path ,
191179 )
192- self .dataproc_submit (job )
193- return job
180+ return DataprocIngestionJob (self .dataproc_submit (job_params ))
0 commit comments