diff --git a/google_sheets/app.py b/google_sheets/app.py index af1d917..c5b407c 100644 --- a/google_sheets/app.py +++ b/google_sheets/app.py @@ -13,6 +13,7 @@ from .google_api import ( build_service, create_sheet_f, + get_all_sheet_titles_f, get_files_f, get_google_oauth_url, get_sheet_f, @@ -238,3 +239,29 @@ async def get_all_file_names( # create dict where key is id and value is name files_dict = {file["id"]: file["name"] for file in files} return files_dict + + +@app.get( + "/get-all-sheet-titles", + description="Get all sheet titles within a Google Spreadsheet", +) +async def get_all_sheet_titles( + user_id: Annotated[ + int, Query(description="The user ID for which the data is requested") + ], + spreadsheet_id: Annotated[ + str, Query(description="ID of the Google Sheet to fetch data from") + ], +) -> List[str]: + service = await build_service(user_id=user_id, service_name="sheets", version="v4") + try: + sheets = await get_all_sheet_titles_f( + service=service, spreadsheet_id=spreadsheet_id + ) + except HttpError as e: + raise HTTPException(status_code=e.status_code, detail=e._get_reason()) from e + except Exception as e: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e) + ) from e + return sheets diff --git a/google_sheets/google_api/__init__.py b/google_sheets/google_api/__init__.py index 9e56cb6..228ee50 100644 --- a/google_sheets/google_api/__init__.py +++ b/google_sheets/google_api/__init__.py @@ -6,6 +6,7 @@ from .service import ( build_service, create_sheet_f, + get_all_sheet_titles_f, get_files_f, get_sheet_f, update_sheet_f, @@ -14,6 +15,7 @@ __all__ = [ "build_service", "create_sheet_f", + "get_all_sheet_titles_f", "get_files_f", "get_google_oauth_url", "get_sheet_f", diff --git a/google_sheets/google_api/service.py b/google_sheets/google_api/service.py index f06f8e2..35ccc5e 100644 --- a/google_sheets/google_api/service.py +++ b/google_sheets/google_api/service.py @@ -13,6 +13,7 @@ __all__ = [ "build_service", "create_sheet_f", + "get_all_sheet_titles_f", "get_files_f", "get_sheet_f", "update_sheet_f", @@ -112,3 +113,10 @@ def create_sheet_f(service: Any, spreadsheet_id: str, title: str) -> None: spreadsheetId=spreadsheet_id, body=body ) request.execute() + + +@asyncify # type: ignore[misc] +def get_all_sheet_titles_f(service: Any, spreadsheet_id: str) -> List[str]: + sheet_metadata = service.spreadsheets().get(spreadsheetId=spreadsheet_id).execute() + sheets = sheet_metadata.get("sheets", "") + return [sheet["properties"]["title"] for sheet in sheets] diff --git a/tests/app/test_app.py b/tests/app/test_app.py index 983ab14..268e2ea 100644 --- a/tests/app/test_app.py +++ b/tests/app/test_app.py @@ -80,6 +80,28 @@ def test_create_sheet( assert response.status_code == expected_status_code +class TestGetAllSheetTitles: + def test_get_all_sheet_titles(self) -> None: + with ( + patch( + "google_sheets.google_api.service._load_user_credentials", + return_value={"refresh_token": "abcdf"}, + ) as mock_load_user_credentials, + patch( + "google_sheets.app.get_all_sheet_titles_f", + return_value=["Sheet1", "Sheet2"], + ) as mock_get_all_sheet_titles, + ): + expected = ["Sheet1", "Sheet2"] + response = client.get( + "/get-all-sheet-titles?user_id=123&spreadsheet_id=abc" + ) + mock_load_user_credentials.assert_called_once() + mock_get_all_sheet_titles.assert_called_once() + assert response.status_code == 200 + assert response.json() == expected + + class TestUpdateSheet: @pytest.mark.parametrize( ("side_effect", "expected_status_code"),