pygsheets

repository·staging·Indexed 23 days ago

https://github.com/nithinmurali/pygsheets

A simple and intuitive Python library for interacting with the Google Spreadsheets API v4. It provides high-level models for spreadsheets, worksheets, cells, and ranges to automate tasks such as data entry, formatting, sharing, and integration with Pandas DataFrames. The library supports OAuth2 authorization, batch modifications for improved performance, and management of named and protected ranges.

Tokens
9.6K
Snippets
23
Records
44
Agent score
82%

What's inside pygsheets

  1. Use Cell Objects

    staging

    A Cell object represents a single cell in a spreadsheet. It has properties like value, value_unformatted, formula, note, and address.

    Linked vs Unlinked Cells

    • Linked Cells: Created via worksheet.cell('A1'). Changes to these objects sync instantaneously with the spreadsheet. If you modify properties like col or value, the spreadsheet updates.
    • Unlinked Cells: Created via Cell('A1', 'value'). These are local models and do not affect the spreadsheet until you explicitly link them using .link(worksheet, True).

    Key Operations

    • cell.fetch(): Fetches the latest data from the spreadsheet for that cell (required if accessing properties other than value directly).
    • cell.neighbour(direction): Gets a neighboring cell (e.g., 'topright' or a tuple like (1, 1)).
    • cell.set_number_format(type, format): Sets the number format.
    • cell.set_text_format(style, value): Sets text styles like 'bold'.
    • cell.update(): Syncs changes for a linked cell.
    # Using linked cells
    c1 = worksheet.cell('B1')
    c1.col = 5  # Now c1 corresponds to E1
    c1.value = "hoho"  # Changes E1
    
    # Get a range of cells
    cell_list = worksheet.range('A1:C7')
    
    # Unlink and relink to update multiple sheets
    c.unlink()
    c.note = "offline note"
    c.link(wks1, True)
    c.link(wks2, True)
    # Getting cell objects
    c1 = Cell('A1',"hello")  # create a unlinked cell
    c1 = worksheet.cell('A1')  # creates a linked cell whose changes syncs instantanously
    cl.value  # Getting cell value
    c1.value_unformatted #Getting cell unformatted value
    c1.formula # Getting cell formula if any
    c1.note # any notes on the cell
    c1.address # address object with cell position
    
    cell_list = worksheet.range('A1:C7')  # get a range of cells 
    cell_list = worksheet.col(5, returnas='cell')  # return all cells in 5th column(E)
  2. Batch Spreadsheet Modifications

    staging

    If you are performing multiple non-value update operations (like merging cells or applying formats), you can use batch mode to group them into a single API call. This improves performance by reducing the number of network requests.

    1. Enable batch mode with gc.set_batch_mode(True).
    2. Perform your operations.
    3. Execute all queued requests with gc.run_batch().
    4. Disable batch mode with gc.set_batch_mode(False).

    Note: Batching does not apply when unlinking a worksheet; those requests are not merged.

    # Enable batch mode
    gc.set_batch_mode(True)
    
    # Queue operations
    wks.merge_cells("A1", "A2")
    wks.merge_cells("B1", "B2")
    Datarange("D1", "D5", wks).apply_format(cell)
    
    # Execute all queued requests
    gc.run_batch()
    
    gc.set_batch_mode(False)
    gc.set_batch_mode(True)
    wks.merge_cells("A1", "A2")
    wks.merge_cells("B1", "B2")
    Datarange("D1", "D5", wks).apply_format(cell)
    gc.run_batch() # All the above requests are executed here
    gc.set_batch_mode(False)
  3. Retain data types using UNFORMATTED_VALUE

    staging
    By default, get_* functions often convert spreadsheet values to strings. To retain the original data types (e.g., integers, floats) instead of receiving formatted strings, set the value_render option to ValueRenderOption.UNFORMATTED_VALUE when calling data retrieval methods.
  4. Use DataRange Objects

    staging

    A DataRange represents a contiguous range of cells. It can be used to apply formatting or manage named/protected ranges.

    Key Features

    • Unbounded Ranges: You can make a range unbounded on rows or columns by setting start_addr or end_addr to specific values (e.g., rng.start_addr = 'A' for all rows in column A).
    • Named Ranges: Assign a name to a range using rng.name = 'my_name'. Use wks.get_named_range('name') to retrieve it.
    • Protected Ranges: Protect a range and specify editors using rng.protected = True and rng.editors = ('users', 'email@example.com').
    • Formatting: Apply a Cell model's format to an entire range using rng.apply_format(model_cell).
    # Getting a Range object
    rng = wks.get_values('A1', 'C5', returnas='range')
    
    rng.name = 'pricesRange'  # Make this a named range
    
    # Protected ranges
    rng.protected = True
    rng.editors = ('users', 'someemail@gmail.com')
    
    # Apply format to a range using a model cell
    model_cell = Cell('A1')
    model_cell.color = (1.0, 0, 1.0, 1.0)
    model_cell.format = (pygsheets.FormatType.PERCENT, '')
    rng.apply_format(model_cell)
    # Getting a Range object
    rng = wks.get_values('A1', 'C5', returnas='range')
    rng.start_addr = 'A' # make the range unbounded on rows <Datarange Sheet1!A:B>
    drange.end_addr = None # make the range unbounded on both axes <Datarange Sheet1>
    
    # Named ranges
    rng.name = 'pricesRange'  # will make this range a named range
    rng = wks.get_named_ranges('commodityCount') # directly get a named range
    rng.name = ''  # will delete this named range
    
    #Protected ranges
    rng.protected = True
    rng.editors = ('users', 'someemail@gmail.com')
    
    # Setting Format
     # first create a model cell with required properties
    model_cell = Cell('A1')
    model_cell.color = (1.0,0,1.0,1.0) # rose color cell
    model_cell.format = (pygsheets.FormatType.PERCENT, '')
    
     # Setting format to multiple cells in one go
    rng.apply_format(model_cell)  # will make all cell in this range rose color and percent format
     # Or if you just want to apply format, you can skip fetching data while creating datarange
    Datarange('A1','A10', worksheet=wks).apply_format(model_cell)
    
    # get cells in range
    cell = rng[0][1]
  5. Understand pygsheets core models

    staging

    The library maps Google Sheets API resources to Python objects. The primary models you will interact with are:

    • Spreadsheet: Represents a Google Spreadsheet file.
    • Worksheet: Represents an individual sheet/tab within a spreadsheet.
    • Cell: Represents a single cell containing data and formatting.
    • DataRange: Represents a collection of cells (a range) within a worksheet.
  6. How pygsheets abstractions work together

    staging

    The library is organized into a hierarchy of objects:

    1. Client: The entry point used to authorize and access spreadsheets. It provides access to the drive (Google Drive API) and sheet (Google Sheets API) functionalities.
    2. Spreadsheet: Represents a single Google Spreadsheet file. A spreadsheet contains one or more worksheets.
    3. Worksheet: Represents an individual sheet within a spreadsheet. This is where most data operations occur.
    4. Cell: Represents a single unit of data. Cells can be manipulated individually to change values, formulas, or formatting.
    5. DataRange: A collection of cells used to perform batch operations on multiple cells at once.
  7. Apply number and color formatting to a range

    staging

    To apply formatting to a specific range, define a pygsheets.Cell object with the desired properties (like set_number_format or color) and use pygsheets.DataRange(...).apply_format(cell) to apply that cell's model to the range.

    Note: When applying colors, the color attribute expects an RGBA tuple (e.g., (1, 1, 1, 0) for white). You can use the fields argument in apply_format to specify exactly which properties to update, such as userEnteredFormat.backgroundColor.

    model_cell = pygsheets.Cell("A1")
    
    model_cell.set_number_format(
        format_type = pygsheets.FormatType.PERCENT,
        pattern = "0%"
    )
    # first apply the percentage formatting
    pygsheets.DataRange(
        left_corner_cell , right_corner_cell , worksheet = wks
    ).apply_format(model_cell)
    
    # now apply the row-colouring interchangeably
    gray_cell = pygsheets.Cell("A1")
    gray_cell.color = (0.9529412, 0.9529412, 0.9529412, 0)
    
    white_cell = pygsheets.Cell("A2")
    white_cell.color = (1, 1, 1, 0)
    
    cells = [gray_cell, white_cell]
    
    for r in range(start_row, end_row + 1):
        print(f"Doing row {r} ...", flush = True, end = "\r")
        wks.get_row(r, returnas = "range").apply_format(cells[ r % 2 ], fields = "userEnteredFormat.backgroundColor")
  8. Authorize using OAuth Credentials

    staging

    OAuth is the best option for editing spreadsheets on behalf of a user. This method allows the script to access all spreadsheets in the user's account. The initial authorization flow (email/password) is only required once.

    Setup Steps:

    1. Configure an OAuth Consent Screen in the Google Developers Console.
    2. Go to Credentials > Create Credentials > OAuth Client ID.
    3. Select Other as the application type.
    4. Download the client_secret[...].json file.

    Usage: By default, pygsheets.authorize() looks for a file named client_secret.json in the current working directory. If your file is named differently or located elsewhere, provide the path using the client_secret parameter.

    Note on Token Storage: After the first authorization, a token file is stored in your working directory. To avoid re-authorizing every time, you can use this token file by passing its path to credentials_directory. Note that credentials_directory overrides client_secret.

  9. Install pygsheets

    staging

    You can install the stable version of pygsheets via pip, or install the latest version directly from the master branch of the GitHub repository.

    To install the stable version:

    pip install pygsheets

    To install the latest version from GitHub:

    pip install https://github.com/nithinmurali/pygsheets/archive/master.zip
    pip install pygsheets
  10. Authorize and open a spreadsheet

    staging

    To use pygsheets, you first need to authorize your session using pygsheets.authorize(). Once authorized, you can use the client to open spreadsheets by their title.

    import pygsheets
    
    client = pygsheets.authorize()
    
    # Open the spreadsheet by its title
    sh = client.open('spreadsheet-title')
    
    # Access the first worksheet in the spreadsheet
    wks = sh.sheet1
    import pygsheets
    
    client = pygsheets.authorize()
    
    # Open the spreadsheet and the first sheet.
    sh = client.open('spreadsheet-title')
    wks = sh.sheet1
  11. Batch API calls using unlink() and link()

    staging

    To improve performance and avoid hitting Google Sheets API rate limits, use wks.unlink() to disconnect the worksheet from the API. You can then perform multiple updates locally (e.g., using wks.update_value()) without triggering individual network requests. Finally, call wks.link() to batch all accumulated changes and send them to the API in a single operation.

    wks.unlink()
    for i in range(10):
        wks.update_value((1, i), i) # wont call api
    wks.link() # will do all the updates