Skip to content

Commit c07bfa5

Browse files
committed
Remove more unnecessary tests
Signed-off-by: Felix Wang <wangfelix98@gmail.com>
1 parent 6ba109d commit c07bfa5

1 file changed

Lines changed: 0 additions & 349 deletions

File tree

sdk/python/tests/integration/offline_store/test_historical_retrieval.py

Lines changed: 0 additions & 349 deletions
Original file line numberDiff line numberDiff line change
@@ -31,221 +31,6 @@
3131

3232
np.random.seed(0)
3333

34-
PROJECT_NAME = "default"
35-
36-
37-
def stage_driver_hourly_stats_parquet_source(directory, df):
38-
# Write to disk
39-
driver_stats_path = os.path.join(directory, "driver_stats.parquet")
40-
df.to_parquet(path=driver_stats_path, allow_truncated_timestamps=True)
41-
return FileSource(
42-
path=driver_stats_path,
43-
event_timestamp_column="event_timestamp",
44-
created_timestamp_column="",
45-
)
46-
47-
48-
def stage_driver_hourly_stats_bigquery_source(df, table_id):
49-
client = bigquery.Client()
50-
df.reset_index(drop=True, inplace=True)
51-
job = _write_df_to_bq(client, df, table_id)
52-
job.result()
53-
54-
55-
def create_driver_hourly_stats_feature_view(source):
56-
driver_stats_feature_view = FeatureView(
57-
name="driver_stats",
58-
entities=["driver"],
59-
features=[
60-
Feature(name="conv_rate", dtype=ValueType.FLOAT),
61-
Feature(name="acc_rate", dtype=ValueType.FLOAT),
62-
Feature(name="avg_daily_trips", dtype=ValueType.INT32),
63-
],
64-
batch_source=source,
65-
ttl=timedelta(hours=2),
66-
)
67-
return driver_stats_feature_view
68-
69-
70-
def stage_customer_daily_profile_parquet_source(directory, df):
71-
customer_profile_path = os.path.join(directory, "customer_profile.parquet")
72-
df.to_parquet(path=customer_profile_path, allow_truncated_timestamps=True)
73-
return FileSource(
74-
path=customer_profile_path,
75-
event_timestamp_column="event_timestamp",
76-
created_timestamp_column="created",
77-
)
78-
79-
80-
def feature_service(name: str, views) -> FeatureService:
81-
return FeatureService(name, views)
82-
83-
84-
def stage_customer_daily_profile_bigquery_source(df, table_id):
85-
client = bigquery.Client()
86-
df.reset_index(drop=True, inplace=True)
87-
job = _write_df_to_bq(client, df, table_id)
88-
job.result()
89-
90-
91-
def create_customer_daily_profile_feature_view(source):
92-
customer_profile_feature_view = FeatureView(
93-
name="customer_profile",
94-
entities=["customer_id"],
95-
features=[
96-
Feature(name="current_balance", dtype=ValueType.FLOAT),
97-
Feature(name="avg_passenger_count", dtype=ValueType.FLOAT),
98-
Feature(name="lifetime_trip_count", dtype=ValueType.INT32),
99-
Feature(name="avg_daily_trips", dtype=ValueType.INT32),
100-
],
101-
batch_source=source,
102-
ttl=timedelta(days=2),
103-
)
104-
return customer_profile_feature_view
105-
106-
107-
# Converts the given column of the pandas records to UTC timestamps
108-
def convert_timestamp_records_to_utc(records, column):
109-
for record in records:
110-
record[column] = utils.make_tzaware(record[column]).astimezone(utc)
111-
return records
112-
113-
114-
# Find the latest record in the given time range and filter
115-
def find_asof_record(records, ts_key, ts_start, ts_end, filter_key, filter_value):
116-
found_record = {}
117-
for record in records:
118-
if record[filter_key] == filter_value and ts_start <= record[ts_key] <= ts_end:
119-
if not found_record or found_record[ts_key] < record[ts_key]:
120-
found_record = record
121-
return found_record
122-
123-
124-
def get_expected_training_df(
125-
customer_df: pd.DataFrame,
126-
customer_fv: FeatureView,
127-
driver_df: pd.DataFrame,
128-
driver_fv: FeatureView,
129-
orders_df: pd.DataFrame,
130-
event_timestamp: str,
131-
full_feature_names: bool = False,
132-
):
133-
# Convert all pandas dataframes into records with UTC timestamps
134-
order_records = convert_timestamp_records_to_utc(
135-
orders_df.to_dict("records"), event_timestamp
136-
)
137-
driver_records = convert_timestamp_records_to_utc(
138-
driver_df.to_dict("records"), driver_fv.batch_source.event_timestamp_column
139-
)
140-
customer_records = convert_timestamp_records_to_utc(
141-
customer_df.to_dict("records"), customer_fv.batch_source.event_timestamp_column
142-
)
143-
144-
# Manually do point-in-time join of orders to drivers and customers records
145-
for order_record in order_records:
146-
driver_record = find_asof_record(
147-
driver_records,
148-
ts_key=driver_fv.batch_source.event_timestamp_column,
149-
ts_start=order_record[event_timestamp] - driver_fv.ttl,
150-
ts_end=order_record[event_timestamp],
151-
filter_key="driver_id",
152-
filter_value=order_record["driver_id"],
153-
)
154-
customer_record = find_asof_record(
155-
customer_records,
156-
ts_key=customer_fv.batch_source.event_timestamp_column,
157-
ts_start=order_record[event_timestamp] - customer_fv.ttl,
158-
ts_end=order_record[event_timestamp],
159-
filter_key="customer_id",
160-
filter_value=order_record["customer_id"],
161-
)
162-
163-
order_record.update(
164-
{
165-
(f"driver_stats__{k}" if full_feature_names else k): driver_record.get(
166-
k, None
167-
)
168-
for k in ("conv_rate", "avg_daily_trips")
169-
}
170-
)
171-
172-
order_record.update(
173-
{
174-
(
175-
f"customer_profile__{k}" if full_feature_names else k
176-
): customer_record.get(k, None)
177-
for k in (
178-
"current_balance",
179-
"avg_passenger_count",
180-
"lifetime_trip_count",
181-
)
182-
}
183-
)
184-
185-
# Convert records back to pandas dataframe
186-
expected_df = pd.DataFrame(order_records)
187-
188-
# Move "event_timestamp" column to front
189-
current_cols = expected_df.columns.tolist()
190-
current_cols.remove(event_timestamp)
191-
expected_df = expected_df[[event_timestamp] + current_cols]
192-
193-
# Cast some columns to expected types, since we lose information when converting pandas DFs into Python objects.
194-
if full_feature_names:
195-
expected_column_types = {
196-
"order_is_success": "int32",
197-
"driver_stats__conv_rate": "float32",
198-
"customer_profile__current_balance": "float32",
199-
"customer_profile__avg_passenger_count": "float32",
200-
}
201-
else:
202-
expected_column_types = {
203-
"order_is_success": "int32",
204-
"conv_rate": "float32",
205-
"current_balance": "float32",
206-
"avg_passenger_count": "float32",
207-
}
208-
209-
for col, typ in expected_column_types.items():
210-
expected_df[col] = expected_df[col].astype(typ)
211-
212-
return expected_df
213-
214-
215-
def stage_orders_bigquery(df, table_id):
216-
client = bigquery.Client()
217-
df.reset_index(drop=True, inplace=True)
218-
job = _write_df_to_bq(client, df, table_id)
219-
job.result()
220-
221-
222-
class BigQueryDataSet:
223-
def __init__(self, dataset_name):
224-
self.name = dataset_name
225-
226-
def __enter__(self):
227-
client = bigquery.Client()
228-
dataset = bigquery.Dataset(f"{client.project}.{self.name}")
229-
dataset.location = "US"
230-
print(f"Creating dataset: {dataset}")
231-
dataset = client.create_dataset(dataset, exists_ok=True)
232-
return dataset
233-
234-
def __exit__(self, exc_type, exc_value, exc_traceback):
235-
print("Tearing down BigQuery dataset")
236-
client = bigquery.Client()
237-
dataset_id = f"{client.project}.{self.name}"
238-
239-
client.delete_dataset(dataset_id, delete_contents=True, not_found_ok=True)
240-
print(f"Deleted dataset '{dataset_id}'")
241-
if exc_type:
242-
print(
243-
"***Logging exception {}***".format(
244-
(exc_type, exc_value, exc_traceback)
245-
)
246-
)
247-
248-
24934
def test_feature_name_collision_on_historical_retrieval():
25035

25136
# _validate_feature_refs is the function that checks for colliding feature names
@@ -292,137 +77,3 @@ def test_feature_name_collision_on_historical_retrieval():
29277
"have different names."
29378
)
29479
assert str(error.value) == expected_error_message
295-
296-
297-
@pytest.mark.integration
298-
def test_historical_features_from_bigquery_sources_containing_backfills(capsys):
299-
now = datetime.now().replace(microsecond=0, second=0, minute=0)
300-
tomorrow = now + timedelta(days=1)
301-
302-
entity_dataframe = pd.DataFrame(
303-
data=[
304-
{"driver_id": 1001, "event_timestamp": now + timedelta(days=2)},
305-
{"driver_id": 1002, "event_timestamp": now + timedelta(days=2)},
306-
]
307-
)
308-
309-
driver_stats_df = pd.DataFrame(
310-
data=[
311-
# Duplicated rows simple case
312-
{
313-
"driver_id": 1001,
314-
"avg_daily_trips": 10,
315-
"event_timestamp": now,
316-
"created": tomorrow,
317-
},
318-
{
319-
"driver_id": 1001,
320-
"avg_daily_trips": 20,
321-
"event_timestamp": tomorrow,
322-
"created": tomorrow,
323-
},
324-
# Duplicated rows after a backfill
325-
{
326-
"driver_id": 1002,
327-
"avg_daily_trips": 30,
328-
"event_timestamp": now,
329-
"created": tomorrow,
330-
},
331-
{
332-
"driver_id": 1002,
333-
"avg_daily_trips": 40,
334-
"event_timestamp": tomorrow,
335-
"created": now,
336-
},
337-
]
338-
)
339-
340-
expected_df = pd.DataFrame(
341-
data=[
342-
{
343-
"driver_id": 1001,
344-
"event_timestamp": now + timedelta(days=2),
345-
"avg_daily_trips": 20,
346-
},
347-
{
348-
"driver_id": 1002,
349-
"event_timestamp": now + timedelta(days=2),
350-
"avg_daily_trips": 40,
351-
},
352-
]
353-
)
354-
355-
bigquery_dataset = (
356-
f"test_hist_retrieval_{int(time.time_ns())}_{random.randint(1000, 9999)}"
357-
)
358-
359-
with BigQueryDataSet(bigquery_dataset), TemporaryDirectory() as temp_dir:
360-
gcp_project = bigquery.Client().project
361-
362-
# Entity Dataframe SQL query
363-
table_id = f"{bigquery_dataset}.orders"
364-
stage_orders_bigquery(entity_dataframe, table_id)
365-
entity_df_query = f"SELECT * FROM {gcp_project}.{table_id}"
366-
367-
# Driver Feature View
368-
driver_table_id = f"{gcp_project}.{bigquery_dataset}.driver_hourly"
369-
stage_driver_hourly_stats_bigquery_source(driver_stats_df, driver_table_id)
370-
371-
store = FeatureStore(
372-
config=RepoConfig(
373-
registry=os.path.join(temp_dir, "registry.db"),
374-
project="".join(
375-
random.choices(string.ascii_uppercase + string.digits, k=10)
376-
),
377-
provider="gcp",
378-
offline_store=BigQueryOfflineStoreConfig(
379-
type="bigquery", dataset=bigquery_dataset
380-
),
381-
)
382-
)
383-
384-
driver = Entity(name="driver", join_key="driver_id", value_type=ValueType.INT64)
385-
driver_fv = FeatureView(
386-
name="driver_stats",
387-
entities=["driver"],
388-
features=[Feature(name="avg_daily_trips", dtype=ValueType.INT32)],
389-
batch_source=BigQuerySource(
390-
table_ref=driver_table_id,
391-
event_timestamp_column="event_timestamp",
392-
created_timestamp_column="created",
393-
),
394-
ttl=None,
395-
)
396-
397-
store.apply([driver, driver_fv])
398-
399-
try:
400-
job_from_sql = store.get_historical_features(
401-
entity_df=entity_df_query,
402-
features=["driver_stats:avg_daily_trips"],
403-
full_feature_names=False,
404-
)
405-
406-
start_time = datetime.utcnow()
407-
actual_df_from_sql_entities = job_from_sql.to_df()
408-
end_time = datetime.utcnow()
409-
with capsys.disabled():
410-
print(
411-
str(
412-
f"\nTime to execute job_from_sql.to_df() = '{(end_time - start_time)}'"
413-
)
414-
)
415-
416-
assert sorted(expected_df.columns) == sorted(
417-
actual_df_from_sql_entities.columns
418-
)
419-
assert_frame_equal(
420-
expected_df.sort_values(by=["driver_id"]).reset_index(drop=True),
421-
actual_df_from_sql_entities[expected_df.columns]
422-
.sort_values(by=["driver_id"])
423-
.reset_index(drop=True),
424-
check_dtype=False,
425-
)
426-
427-
finally:
428-
store.teardown()

0 commit comments

Comments
 (0)