11import dagster as dg
22from econ_data_platform .resources .motherduck import MotherDuckResource
3+ from econ_data_platform .resources .google_drive import (
4+ GoogleDriveResource ,
5+ google_drive_resource ,
6+ )
37
48import polars as pl
59from io import StringIO
6- from google .oauth2 import service_account
7- from googleapiclient .discovery import build
10+
811from dataclasses import dataclass
9- from collections .abc import Sequence
1012
1113from datetime import datetime
1214import os
@@ -20,7 +22,9 @@ class DriveFile:
2022 modifiedTime : str
2123
2224
23- def realtor_asset_factory (file_definition : DriveFile ) -> dg .Definitions :
25+ def realtor_asset_factory (
26+ file_definition : DriveFile , google_drive : GoogleDriveResource
27+ ) -> dg .Definitions :
2428 file_name , _ = os .path .splitext (file_definition .name )
2529 file_id = file_definition .id
2630
@@ -30,13 +34,14 @@ def realtor_asset_factory(file_definition: DriveFile) -> dg.Definitions:
3034 kinds = {"polars" , "duckdb" , "google_drive" },
3135 )
3236 def read_csv_from_drive (
33- context : dg .AssetExecutionContext , md : MotherDuckResource
37+ context : dg .AssetExecutionContext ,
38+ md : MotherDuckResource ,
39+ google_drive : GoogleDriveResource ,
3440 ) -> dg .MaterializeResult :
3541 """Read CSV directly from Google Drive file ID into a polars DataFrame"""
3642 context .log .info (f"Reading file { file_name } from Google Drive" )
37- request = service .files ().get_media (fileId = file_id )
38- content = request .execute ()
39- csv_string = content .decode ("utf-8" )
43+ request = google_drive .request_content (file_id )
44+ csv_string = request .decode ("utf-8" )
4045 df = pl .read_csv (StringIO (csv_string ))
4146 md .drop_create_duck_db_table (file_name , df )
4247
@@ -57,14 +62,12 @@ def read_csv_from_drive(
5762 job_name = f"{ file_name } _job" ,
5863 minimum_interval_seconds = 15 ,
5964 )
60- def file_sensor (context ):
65+ def file_sensor (context , google_drive : GoogleDriveResource ):
6166 # Get current modification time from cursor
6267 last_mtime = float (context .cursor ) if context .cursor else 0
6368
6469 # Get file details from Drive
65- file_metadata = (
66- service .files ().get (fileId = file_id , fields = "modifiedTime" ).execute ()
67- )
70+ file_metadata = google_drive .get_file_metadata (file_id )
6871 context .log .info (f"File metadata: { file_metadata } " )
6972
7073 current_mtime = datetime .strptime (
@@ -83,24 +86,16 @@ def file_sensor(context):
8386 assets = [read_csv_from_drive ],
8487 jobs = [file_job ],
8588 sensors = [file_sensor ],
89+ resources = {"google_drive" : google_drive },
8690 )
8791
8892
89- SCOPES = ["https://www.googleapis.com/auth/drive.readonly" ]
90- credentials = service_account .Credentials .from_service_account_file (
91- "creds.json" , scopes = SCOPES
92- )
93- service = build ("drive" , "v3" , credentials = credentials )
93+ # Fetch files from the Google Drive folder using properly initialized _client
9494folder_id = os .environ .get ("GOOGLE_DRIVE_FOLDER_ID" , "" )
95+ file_results = google_drive_resource .retrieve_files (folder_id ).get ("files" , [])
9596
96- # Get files from folder
97- query = f"'{ folder_id } ' in parents and mimeType='text/csv'"
98- results = (
99- service .files ()
100- .list (q = query , fields = "files(id, name, createdTime, modifiedTime)" )
101- .execute ()
102- )
103-
97+ # Create realtor definitions dynamically
10498realtor_definitions = [
105- realtor_asset_factory (DriveFile (** file )) for file in results .get ("files" , [])
99+ realtor_asset_factory (DriveFile (** file ), google_drive_resource )
100+ for file in file_results
106101]
0 commit comments