Version 42.0.0.20250416
of the Python SDK represents a full rewrite of the SDK with a number of breaking changes, outlined in the following sections. When upgrading to this version or later versions, take note of the changes in the SDK, including client construction and parameter names. If necessary, you can use the legacy version of the SDK along with the latest version.
SDK versions 41.0.0.20250319
and earlier continue to function as expected, but you should plan to update your integration as soon as possible to ensure continued support.
The new version of the Python SDK introduces breaking changes in the client class.
// LEGACY import os from square_legacy.client import Client as LegacySquare client = LegacySquare( environment="sandbox", access_token=os.environ.get("SQUARE_TOKEN") ) // NEW import os from square import Square from square.environment import SquareEnvironment client = Square( environment=SquareEnvironment.SANDBOX, token=os.environ.get("SQUARE_TOKEN") )
Legacy | New | Additional information |
---|---|---|
environment | environment | An enumeration for specifying the environment (SANDBOX or PRODUCTION ). |
access_token | token | The access token used for authentication. |
custom_url | base_url | The base URL for API requests. |
square_version | version | The Square API version to use. |
additional_headers | additional_headers | Additional headers can be set at individual methods. |
http_call_back | Removed | This option has been removed. |
user_agent_detail | Removed | This option has been removed. |
While the new SDK has many improvements, it takes time to upgrade when there are breaking changes. To make the migration easier, the old SDK is published as squareup_legacy
so that the two SDKs can be used side by side in the same project.
The following example shows how to use the new and legacy SDKs inside a single file:
from square_legacy.client import Client as LegacySquare from square import Square def main(): client = Square(token=os.environ.get("SQUARE_TOKEN")) legacy_client = LegacySquare(access_token=os.environ.get("SQUARE_TOKEN")) # List all payments with the new client. new_response = client.payments.list() # List all payments with the legacy client. legacy_response = legacy_client.payments.list_payments()
You should migrate to the new SDK using the following steps:
- Upgrade the PyPi package to
^42.0.0
. - Run
pip install squareup_legacy
. - Search and replace all requires and imports from
square
tosquare_legacy
. - Gradually introduce methods from the new SDK by importing them from the Square import.
The previous version of the SDK relied on simple Python dictionaries to represent request body properties. For example, consider the following method call required to create a customer:
// LEGACY response = client.customers.create_customer( { "idempotency_key": str(uuid.uuid4()), "given_name": 'given-vs1', "family_name": 'family-vs1', "address": { "address_line_1": '1955 Broadway', "address_line_2": 'Oakland, CA 94612' } )
In the new SDK, requests are now defined with TypedDict
types. The UX is similar, but you're now presented with **kwargs
for each parameter to better guide you through the expected set of parameters.
// NEW response = client.customers.create( idempotency_key=str(uuid.uuid4()), given_name="given-vs1", family_name="family-vs1", address={ "address_line_1": "1955 Broadway", "address_line_2": "Oakland, CA 94612" } )
The new SDK uses Pydantic, a popular Python validation library, to define response models. With this, response types now have a better autocompletion experience and properties can be accessed with dot-notation rather than free-form dictionary access.
// LEGACY response = client.locations.list_locations() location = response.body['locations'][0] name = location['name'] // NEW response = client.locations.list() location_name = response.locations[0] name = location.name
The legacy SDK represents successful calls and errors with the same ApiResponse
type. Users could distinguish between successes and errors as shown:
// LEGACY response = client.locations.list_locations() if response.is_success(): for location in response.body['locations']: print(f"{location['id']}: ", end="") print(f"{location['name']}, ", end="") print(f"{location['address']['address_line_1']}, ", end="") print(f"{location['address']['locality']}") elif response.is_error(): for error in response.errors: print(error['category']) print(error['code']) print(error['detail'])
The new SDK represents errors as Exceptions
, all of which inherit from the ApiError
class. The ApiError
class includes the Square Error
type.
from square.core.api_error import ApiError try: response = client.locations.list() for location in response.items: print(f"{location.id}: ", end="") print(f"{location.name}, ", end="") print(f"{location.address.address_line_1}, ", end="") print(f"{location.address.locality}") except ApiError as e: for error in e.errors: print(error.category) print(error.code) print(error.detail)
Square's paginated endpoints now support auto-pagination with an iterator. Callers don't need to manually fetch the next page. You can now iterate over the entire list and the client automatically fetches the next page behind the scenes.
The following example shows the same code, with the legacy and new SDKs:
// LEGACY result = client.customers.list_customers( limit=10, sort_field='DEFAULT', sort_order='DESC' ) if result.is_success(): while (result.body != {}): for cust in result.body['customers']: print(f"customer: ID: {cust['id']}, ", end="") print(f"Version: {cust['version']}, ", end="") print(f"Given name: {cust['given_name']}, ", end="") print(f"Family name: {cust['family_name']}") if (result.cursor): result = client.customers.list_customers( limit=limit, sort_field='DEFAULT', sort_order='DESC', cursor=result.cursor ) else: break elif result.is_error(): for error in result.errors: print(error['category']) print(error['code']) print(error['detail']) // NEW try: response = client.customers.list( limit=10, sort_field='DEFAULT', sort_order='DESC' ) for customer in response: print(f"customer: ID: {customer.id}, ", end="") print(f"Version: {cutomer.version}, ", end="") print(f"Given name: {customer.given_name}, ", end="") print(f"Family name: {customer.family_name}") except ApiError as e: for error in e.errors: print(error.category) print(error.code) print(error.detail)