70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
"""
|
|
Spreadsheet models with self-parsing from Google Sheets API responses.
|
|
"""
|
|
|
|
from pydantic import BaseModel
|
|
from typing import Optional, List
|
|
|
|
|
|
class SheetInfo(BaseModel):
|
|
"""Individual sheet within a spreadsheet."""
|
|
title: str
|
|
sheet_id: int
|
|
index: int
|
|
row_count: int
|
|
column_count: int
|
|
|
|
|
|
class SpreadsheetMetadata(BaseModel):
|
|
"""Spreadsheet metadata."""
|
|
spreadsheet_id: str
|
|
title: str
|
|
locale: Optional[str] = None
|
|
timezone: Optional[str] = None
|
|
sheets: List[SheetInfo] = []
|
|
|
|
@classmethod
|
|
def from_google(cls, data: dict) -> "SpreadsheetMetadata":
|
|
"""Parse from Google Sheets API response."""
|
|
sheets = [
|
|
SheetInfo(
|
|
title=sheet["properties"]["title"],
|
|
sheet_id=sheet["properties"]["sheetId"],
|
|
index=sheet["properties"]["index"],
|
|
row_count=sheet["properties"]["gridProperties"].get("rowCount", 0),
|
|
column_count=sheet["properties"]["gridProperties"].get("columnCount", 0),
|
|
)
|
|
for sheet in data.get("sheets", [])
|
|
]
|
|
|
|
return cls(
|
|
spreadsheet_id=data["spreadsheetId"],
|
|
title=data["properties"]["title"],
|
|
locale=data["properties"].get("locale"),
|
|
timezone=data["properties"].get("timeZone"),
|
|
sheets=sheets,
|
|
)
|
|
|
|
|
|
class SheetValues(BaseModel):
|
|
"""Sheet data values."""
|
|
spreadsheet_id: str
|
|
range: str
|
|
values: List[List[str]] # rows of cells
|
|
row_count: int
|
|
column_count: int
|
|
|
|
@classmethod
|
|
def from_google(cls, spreadsheet_id: str, range_name: str, values: List[List]) -> "SheetValues":
|
|
"""Parse from Google Sheets API values response."""
|
|
row_count = len(values)
|
|
column_count = max((len(row) for row in values), default=0)
|
|
|
|
return cls(
|
|
spreadsheet_id=spreadsheet_id,
|
|
range=range_name,
|
|
values=values,
|
|
row_count=row_count,
|
|
column_count=column_count,
|
|
)
|