Code Monkey home page Code Monkey logo

connect-python-sdk's Introduction

Square logo

Square Connect Python SDK - RETIRED


Build Status PyPI version Apache-2 license

NOTICE: Square Connect Python SDK retired

The Square Connect Python SDK is retired (EOL) as of 2019-08-15 and will no longer receive bug fixes or product updates. To continue receiving API and SDK improvements, please follow the instructions below to migrate to the new Square Python SDK.

The old Connect SDK documentation is available under the /docs folder.





Migrate to the Square Python SDK

Follow the instructions below to migrate your apps from the deprecated squareconnect library to the new square library.

Install the new library

Install the latest Square Python SDK using pip:

pip install squareup

Update your code

  1. Change all instances of import 'squareconnect' to import 'square'.
  2. Replace models with plain Python dictionary equivalents.
  3. Update client instantiation to follow the method outlined below.
  4. Update code for accessing response data to follow the method outlined below.
  5. Check response.is_success or response.is_error rather than rescuing exceptions for flow control.

To simplify your code, we also recommend that you use method chaining to access APIs instead of explicitly instantiating multiple clients.

Client instantiation

from square.client import Client

square = Client(access_token='YOUR ACCESS TOKEN')

response = square.API.ENDPOINT(body=BODY)

Accessing response data

if response.is_success():
  print({response.body})
elif response.is_error():
  print({response.errors})

An example code migration

As a specific example, consider the following code for creating a new customer from this dictionary:

new_customer = {
  'given_name': 'Ava',
  'address': {
    'address_line_1': '555 Electric Ave',
    'locality': 'Los Angeles',
    'country': 'US'
  }
}

With the deprecated squareconnect library, this is how you instantiate a client for the Customers API, format the request, and call the endpoint:

from squareconnect import ApiClient
from squareconnect.rest import ApiException
from squareconnect.apis.customers_api import CustomersApi
from squareconnect.models.create_customer_request import CreateCustomerRequest

# Instantiate and initialize the client
api_client = ApiClient()
api_client.configuration.access_token = 'YOUR ACCESS TOKEN'

# Get an instance of the Square API you want call
api_instance = CustomersApi(api_client)

# Build the request
create_customer_request = CreateCustomerRequest(
  given_name=new_customer['given_name'],
  address=new_customer['address'],
)

# Call create_customer method to create a new customer and handle the response
try:
  api_response = api_instance.create_customer(create_customer_request)
  print(f"Success: {api_response.customer}")
except ApiException as err:
  print(f"Exception when calling CustomersApi->create_customer: {err}")

Now consider equivalent code using the new square library:

from square.client import Client

# Instantiate the client
client = Client(access_token='YOUR ACCESS TOKEN')

# Call create_customer method to create a new customer
result = client.customers.create_customer(new_customer)

# Handle the result
if result.is_success():
  # Display the response as text
  print(f"Success: {result.text}")
# Call the error method to see if the call failed
elif result.is_error():
  print(f"Errors: {result.errors}")

That's it! What was once a multi-block process can be handled in 2 lines of code and an if/elif block. Migrating to the square library reduces boilerplate and lets you can focus on the parts of your code that really matter.




Ask the community

Please join us in our Square developer community if you have any questions!

Square Python SDK

connect-python-sdk's People

Contributors

alecholmes avatar bunnyc1986 avatar frojasg avatar goblinhorde avatar havenwood avatar hukid avatar jguinta avatar jlabanca avatar mikekono avatar rck109d avatar square-sdk-deployer avatar ssung88 avatar ti55987 avatar tristansokol avatar yonpols avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

connect-python-sdk's Issues

Why are there no product names in transactions?

In order to integrate my system, I need to be able to determine which product is purchased in the squareup store. But I did not see anything about it in the API documentation. Can you help me with this?

search_orders cannot handle refunds

Hello, thank you for the great sdk. I'm running into an issues, that I've narrowed to what I think is a bug in the sdk.

query = SearchOrdersQuery(
                filter=SearchOrdersFilter(
                    date_time_filter=SearchOrdersDateTimeFilter(
                        created_at=TimeRange(
                            start_at='2019-05-18T04:50:00.05Z',
                            end_at='2019-05-18T05:00:00.05Z'
                        )
                    )
                )
            )
            search_request = SearchOrdersRequest(
                location_ids=[location.square_location],
                query=query
            )
            orders = api.search_orders(body=search_request).orders

throws an error because in this range there is a refunded order.

raceback (most recent call last):
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/eroncancio/dev/comidalista/mysite/comidalista/views.py", line 65, in square_orders
    square.refresh_orders(location)
  File "/Users/eroncancio/dev/comidalista/mysite/comidalista/squareup.py", line 121, in refresh_orders
    orders = api.search_orders(body=search_request).orders
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/apis/orders_api.py", line 287, in search_orders
    callback=params.get('callback'))
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 316, in call_api
    response_type, auth_settings, callback)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 149, in __call_api
    deserialized_data = self.deserialize(response_data, response_type)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 236, in deserialize
    return self.__deserialize(data, response_type)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 279, in __deserialize
    return self.__deserialize_model(data, klass)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 569, in __deserialize_model
    setattr(instance, attr, self.__deserialize(value, attr_type))
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 254, in __deserialize
    for sub_data in data]
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 254, in <listcomp>
    for sub_data in data]
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 279, in __deserialize
    return self.__deserialize_model(data, klass)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 569, in __deserialize_model
    setattr(instance, attr, self.__deserialize(value, attr_type))
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 279, in __deserialize
    return self.__deserialize_model(data, klass)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 569, in __deserialize_model
    setattr(instance, attr, self.__deserialize(value, attr_type))
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 279, in __deserialize
    return self.__deserialize_model(data, klass)
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/api_client.py", line 569, in __deserialize_model
    setattr(instance, attr, self.__deserialize(value, attr_type))
  File "/Users/eroncancio/dev/comidalista/python3/lib/python3.7/site-packages/squareconnect/models/money.py", line 76, in amount
    raise ValueError("Invalid value for `amount`, must be a value greater than or equal to `0`")
ValueError: Invalid value for `amount`, must be a value greater than or equal to `0`

if call the API directly, I get

{
    "orders": [
        {
            "id": "5lz72ezvoM6ZP3nBUBbfcOmeV",
            "location_id": "BVXZNP19P4B8M",
            "created_at": "2019-05-18T04:50:13.000Z",
            "updated_at": "2019-05-18T04:50:13.000Z",
            "state": "COMPLETED",
            "total_tax_money": {
                "amount": 0,
                "currency": "COP"
            },
            "total_discount_money": {
                "amount": 0,
                "currency": "COP"
            },
            "total_tip_money": {
                "amount": 0,
                "currency": "COP"
            },
            "total_money": {
                "amount": 0,
                "currency": "COP"
            },
            "closed_at": "2019-05-18T04:50:14.000Z",
            "total_service_charge_money": {
                "amount": 0,
                "currency": "COP"
            },
            "returns": [
                {
                    "source_order_id": "lfB1KZ2yjD5bUB20818Fbc0eV",
                    "return_line_items": [
                        {
                            "uid": "fbfdb44f-0915-4a28-8919-0d9b094ae45b:W0DbiIEocS2gwvsYty85S",
                            "source_line_item_uid": "2179bb79-91c8-49bc-b961-93973d1305ac",
                            "name": "Mazorcada",
                            "quantity": "1",
                            "catalog_object_id": "6AXBWS766ZTXVODWS5WNL4KE",
                            "variation_name": "9-59",
                            "return_taxes": [
                                {
                                    "uid": "4a414b61-0429-410a-8be6-b80c6ad6414d",
                                    "catalog_object_id": "5GMRKM2QFGT6YVGK3ZBZRKGI",
                                    "name": "Ipoconsumo",
                                    "type": "INCLUSIVE",
                                    "percentage": "8",
                                    "applied_money": {
                                        "amount": 62992,
                                        "currency": "COP"
                                    },
                                    "scope": "LINE_ITEM"
                                },
                                {
                                    "uid": "d12cfe7d-da61-455d-b2b6-9fe13d49b8b2",
                                    "catalog_object_id": "LE7U5EGXLAPW5AYWY5EOHSTG",
                                    "name": "IVA",
                                    "type": "INCLUSIVE",
                                    "percentage": "19",
                                    "applied_money": {
                                        "amount": 149606,
                                        "currency": "COP"
                                    },
                                    "scope": "LINE_ITEM"
                                }
                            ],
                            "base_price_money": {
                                "amount": 1000000,
                                "currency": "COP"
                            },
                            "variation_total_price_money": {
                                "amount": 1000000,
                                "currency": "COP"
                            },
                            "gross_return_money": {
                                "amount": 787402,
                                "currency": "COP"
                            },
                            "total_tax_money": {
                                "amount": 212598,
                                "currency": "COP"
                            },
                            "total_discount_money": {
                                "amount": 0,
                                "currency": "COP"
                            },
                            "total_money": {
                                "amount": 1000000,
                                "currency": "COP"
                            }
                        },
                        {
                            "uid": "fbfdb44f-0915-4a28-8919-0d9b094ae45b:OucU6xkdpI2KqcMcBGA6S",
                            "source_line_item_uid": "26640888-31ad-4ef0-bfa0-5d4d4cc4806e",
                            "name": "Adición Pollo",
                            "quantity": "1",
                            "catalog_object_id": "D2NR5EFTBKZLNSA6ODARYFBQ",
                            "variation_name": "",
                            "return_taxes": [
                                {
                                    "uid": "4a414b61-0429-410a-8be6-b80c6ad6414d",
                                    "catalog_object_id": "5GMRKM2QFGT6YVGK3ZBZRKGI",
                                    "name": "Ipoconsumo",
                                    "type": "INCLUSIVE",
                                    "percentage": "8",
                                    "applied_money": {
                                        "amount": 22222,
                                        "currency": "COP"
                                    },
                                    "scope": "LINE_ITEM"
                                }
                            ],
                            "base_price_money": {
                                "amount": 300000,
                                "currency": "COP"
                            },
                            "variation_total_price_money": {
                                "amount": 300000,
                                "currency": "COP"
                            },
                            "gross_return_money": {
                                "amount": 277778,
                                "currency": "COP"
                            },
                            "total_tax_money": {
                                "amount": 22222,
                                "currency": "COP"
                            },
                            "total_discount_money": {
                                "amount": 0,
                                "currency": "COP"
                            },
                            "total_money": {
                                "amount": 300000,
                                "currency": "COP"
                            }
                        },
                        {
                            "uid": "fbfdb44f-0915-4a28-8919-0d9b094ae45b:ED3XWoBHwQcwvce4V965S",
                            "source_line_item_uid": "ffcbd1c2-8398-4cee-bff5-35126ab063b5",
                            "name": "Tacos",
                            "quantity": "2",
                            "catalog_object_id": "CHQCX5K6EUHFXP33ZOR2YMPO",
                            "variation_name": "",
                            "return_taxes": [
                                {
                                    "uid": "4a414b61-0429-410a-8be6-b80c6ad6414d",
                                    "catalog_object_id": "5GMRKM2QFGT6YVGK3ZBZRKGI",
                                    "name": "Ipoconsumo",
                                    "type": "INCLUSIVE",
                                    "percentage": "8",
                                    "applied_money": {
                                        "amount": 7407,
                                        "currency": "COP"
                                    },
                                    "scope": "LINE_ITEM"
                                }
                            ],
                            "base_price_money": {
                                "amount": 50000,
                                "currency": "COP"
                            },
                            "variation_total_price_money": {
                                "amount": 100000,
                                "currency": "COP"
                            },
                            "gross_return_money": {
                                "amount": 92593,
                                "currency": "COP"
                            },
                            "total_tax_money": {
                                "amount": 7407,
                                "currency": "COP"
                            },
                            "total_discount_money": {
                                "amount": 0,
                                "currency": "COP"
                            },
                            "total_money": {
                                "amount": 100000,
                                "currency": "COP"
                            }
                        },
                        {
                            "uid": "fbfdb44f-0915-4a28-8919-0d9b094ae45b:KaVbb0E4egQ2qctd6Pu5S",
                            "source_line_item_uid": "79375281-4a3c-494e-be3b-3d7b451e1747",
                            "name": "Adición Sobrebarriga",
                            "quantity": "1",
                            "catalog_object_id": "AEZPFVELAFRBB4Z57B7F7HLQ",
                            "variation_name": "Normal",
                            "return_taxes": [
                                {
                                    "uid": "4a414b61-0429-410a-8be6-b80c6ad6414d",
                                    "catalog_object_id": "5GMRKM2QFGT6YVGK3ZBZRKGI",
                                    "name": "Ipoconsumo",
                                    "type": "INCLUSIVE",
                                    "percentage": "8",
                                    "applied_money": {
                                        "amount": 22222,
                                        "currency": "COP"
                                    },
                                    "scope": "LINE_ITEM"
                                }
                            ],
                            "base_price_money": {
                                "amount": 300000,
                                "currency": "COP"
                            },
                            "variation_total_price_money": {
                                "amount": 300000,
                                "currency": "COP"
                            },
                            "gross_return_money": {
                                "amount": 277778,
                                "currency": "COP"
                            },
                            "total_tax_money": {
                                "amount": 22222,
                                "currency": "COP"
                            },
                            "total_discount_money": {
                                "amount": 0,
                                "currency": "COP"
                            },
                            "total_money": {
                                "amount": 300000,
                                "currency": "COP"
                            }
                        },
                        {
                            "uid": "fbfdb44f-0915-4a28-8919-0d9b094ae45b:ojAo4lZrD3kcYvxHSHy5S",
                            "source_line_item_uid": "6f72ea40-ec2c-45c8-85a3-88e278e2d979",
                            "name": "Adición Pollo",
                            "quantity": "1",
                            "catalog_object_id": "D2NR5EFTBKZLNSA6ODARYFBQ",
                            "variation_name": "",
                            "return_taxes": [
                                {
                                    "uid": "4a414b61-0429-410a-8be6-b80c6ad6414d",
                                    "catalog_object_id": "5GMRKM2QFGT6YVGK3ZBZRKGI",
                                    "name": "Ipoconsumo",
                                    "type": "INCLUSIVE",
                                    "percentage": "8",
                                    "applied_money": {
                                        "amount": 22223,
                                        "currency": "COP"
                                    },
                                    "scope": "LINE_ITEM"
                                }
                            ],
                            "base_price_money": {
                                "amount": 300000,
                                "currency": "COP"
                            },
                            "variation_total_price_money": {
                                "amount": 300000,
                                "currency": "COP"
                            },
                            "gross_return_money": {
                                "amount": 277777,
                                "currency": "COP"
                            },
                            "total_tax_money": {
                                "amount": 22223,
                                "currency": "COP"
                            },
                            "total_discount_money": {
                                "amount": 0,
                                "currency": "COP"
                            },
                            "total_money": {
                                "amount": 300000,
                                "currency": "COP"
                            }
                        }
                    ],
                    "return_taxes": [
                        {
                            "uid": "4a414b61-0429-410a-8be6-b80c6ad6414d",
                            "catalog_object_id": "5GMRKM2QFGT6YVGK3ZBZRKGI",
                            "name": "Ipoconsumo",
                            "type": "INCLUSIVE",
                            "percentage": "8",
                            "applied_money": {
                                "amount": 137066,
                                "currency": "COP"
                            },
                            "scope": "LINE_ITEM"
                        },
                        {
                            "uid": "d12cfe7d-da61-455d-b2b6-9fe13d49b8b2",
                            "catalog_object_id": "LE7U5EGXLAPW5AYWY5EOHSTG",
                            "name": "IVA",
                            "type": "INCLUSIVE",
                            "percentage": "19",
                            "applied_money": {
                                "amount": 149606,
                                "currency": "COP"
                            },
                            "scope": "LINE_ITEM"
                        }
                    ]
                }
            ],
            "return_amounts": {
                "total_money": {
                    "amount": 2000000,
                    "currency": "COP"
                },
                "tax_money": {
                    "amount": 286672,
                    "currency": "COP"
                },
                "discount_money": {
                    "amount": 0,
                    "currency": "COP"
                },
                "tip_money": {
                    "amount": 0,
                    "currency": "COP"
                },
                "service_charge_money": {
                    "amount": 0,
                    "currency": "COP"
                }
            },
            "net_amounts": {
                "total_money": {
                    "amount": -2000000,
                    "currency": "COP"
                },
                "tax_money": {
                    "amount": -286672,
                    "currency": "COP"
                },
                "discount_money": {
                    "amount": 0,
                    "currency": "COP"
                },
                "tip_money": {
                    "amount": 0,
                    "currency": "COP"
                },
                "service_charge_money": {
                    "amount": 0,
                    "currency": "COP"
                }
            },
            "refunds": [
                {
                    "id": "8BmWczV2O6oietHro7q5S",
                    "location_id": "BVXZNP19P4B8M",
                    "transaction_id": "lfB1KZ2yjD5bUB20818Fbc0eV",
                    "tender_id": "xF7wXYLmlfKNsdMaZkltKQB",
                    "created_at": "2019-05-18T04:50:13Z",
                    "reason": "Cargo accidental",
                    "amount_money": {
                        "amount": 2000000,
                        "currency": "COP"
                    },
                    "status": "APPROVED"
                }
            ]
        }
    ]
}

i think those negative numbers are tripping up the SDK

Backward incompatible change to handling access_token not mentioned in CHANGES.md

I found that after upgrading from 2.5.1 to 2.20181212.0 I was getting errors like this from list_locations():

ApiException: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'content-length': '569', 'X-Xss-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'X-Download-Options': 'noopen', 'Strict-Transport-Security': 'max-age=631152000', 'Vary': 'Origin, Accept-Encoding', 'keep-alive': 'timeout=60', 'X-Permitted-Cross-Domain-Policies': 'none', 'Date': 'Mon, 21 Jan 2019 18:56:04 GMT', 'X-Frame-Options': 'SAMEORIGIN', 'Content-Type': 'application/json'})
HTTP response body: {"errors":[{"category":"AUTHENTICATION_ERROR","code":"UNAUTHORIZED","detail":"The `Authorization` http header of your request was malformed. The header value is expected to be of the format \"Bearer TOKEN\" (without quotation marks), where TOKEN is to be replaced with your access token (e.g. \"Bearer ABC123def456GHI789jkl0\"). For more information, see https://docs.connect.squareup.com/api/connect/v2/#requestandresponseheaders. If you are seeing this error message while using one of our officially supported SDKs, please report this to [email protected]."}]}

Eventually I traced this to the method of passing in access_token having changed.
It used to be you would set it globally on squareconnect.configuration.access_token.
That no longer works and you have to set api.api_client.configuration.access_token.

This apparently changed sometime after 2.9.0

Should really be noted in the CHANGES.md file since it's a major backward incompatibility that breaks auth for anyone who upgrades.

I did see this: "Remove singleton constraint for configuration class. This is a minor breaking change to ApiClient and RESTClientObject initialization."

Not sure if that's about the same thing, but if so I don't think this is adequate notice, because a) the fix requires changing every line of my code that instantiates a square api, and b) this doesn't tell the reader anything about what to do.
I only figured it out by re-reading the README and noticing the example had changed.

Maximum tender amount off by an order of magnitude in Money model? Results in deserialization of legitimate response throwing a ValueError

Hi there,

We ran into a funny issue where it looks like somebody specified the maximum possible "tendered" amount for a fake/test cash transaction of: 999,999,999 cents, corresponding to $9,999,999.99

This value came through in the buyer_tendered_money TenderCashDetails field.

The outcome was a ValueError thrown inside the SquareConnectAPI money.py model:
https://github.com/square/connect-python-sdk/blob/master/squareconnect/models/money.py#L75

if amount > 99999999:
    raise ValueError("Invalid value for `amount`, must be a value less than or equal to `99999999`")

This value, 99,999,999, seems to be off by a digit from the actual maximum allowable value (999,999,999) inside the Square Point of Sale app, resulting in a "legitimate" tender value from the Connect API v2 endpoint yielding an exception during deserialization.

I'm guessing this issue is upstream in the underlying swagger spec that generates the Python SDK. So this problem may be present in all instances of the Connect SDK. Looks like somebody just mis-typed the constant here for the maximum valid Money model value in the spec?

Anyway, this was problematic for us because this single illegitimate amount raised an exception, yielding a deserialization failure for a whole page of otherwise legitimate transaction results.

Long live languages that support underscores in numeric literals!
Added to Python in 3.6 FWIW, but again, guessing a deficit of Swagger / the underlying spec caused this problem.

Options for tuning connection pool size and other concurrency parameters on the underlying RESTClientObject?

Hi there,

There doesn't seen to be a nice "ordained" way to tune the connection pool size of the RESTClientObject that the Python SDK depends on.

And, reading through the source code, I feel like there may be a mixup between the num_pools=pools_size parameter currently in use and a different parameter to actually control the number of workers in a connection pool.

From reading the urllib3 documentation, it appears that:

num_pools is a higher-order parameter that controls the number of connection pools via urllib3's PoolManager object, with each pool corresponding to requests issued to a specific distinct domain name (e.g. google.com vs. yahoo.com):

:param num_pools:
        Number of connection pools to cache before discarding the least
        recently used pool.

Whereas the maxsize parameter of an individual urllib3 ConnectionPool object seems to actually control the number of concurrent & reusable request connections allowable for a given domain.

Since all of the Square Connect APIs are under the same domain (connect.squareup.com), wouldn't it make sense to expose, say in the Configuration object:

  • maxsize
  • block
  • and maybe even the retries policy?

Is the expected "official" way of doing this to manually create:

  • a custom ApiClient object
    • with a custom rest_client object instance
      • with a custom pools_manager object instance with: maxsize, block, etc. all passed in as keyword arguments?

And then to pass a customized ApiClient instance into the individual Connect API initializers?

That seems like a whole lot of custom!

It just feels a little messy relative to exposing these paramaters in a more first-class way via the Configuration object.

Would love to hear about the rationale behind this. Worried about people shooting themselves in the foot by configuring concurrency settings? Or maybe I am fundamentally misunderstanding something here?

Would be great to see the Configuration object support a catch-all parameter for open-ended kwargs to pass into the RESTClientObject.pool_manager attribute. Or an "ordained" subset of parameters such as maxsize, block, and retries.

This SDK is largely generated from the swagger codegen tool, right?
So maybe my beef is actually further upstream with the swagger project?

Thanks for taking the time to read this.
Hope it is clear, and my apologies if I am fundamentally misunderstanding the affordances available for configuring concurrency via this SDK!

The squareconnect.configuration object can become corrupted

Despite what the contribution guidelines say (no issues, pulls, suggestions, or requests) @tristansokol asked me to open this issue for further discussion.

Because the squareconnect.configuration is a library level global. The instance is vulnerable to becoming corrupt. A race condition exists where the access_token could be set, [changed by a different thread], and then accessed causing an error that would be very difficult for clients to track down.

The squareconnect.configuration shouldn't be a library global, shouldn't be coerced into a singleton, and (if a configuration class is really the way you want to handle setup/init), should be internal to each API, or at the very least; a variable held by an additional API wrapper that can be passed to each lower API during creation.

@tristansokol suggested that changing the access_token after setting it is a valid use case you need to support, but I'm unable to think of a use case that won't make me sad to read if I later had to maintain said code.

@robinlinden

Order fulfillment shipment_details

Order fulfillment resources returned from the API contain shipment_details, not pickup_details key:

{
    "uid": "INUz2yWXRsAMZLY3YoC2lB",
    "type": "SHIPMENT",
    "state": "COMPLETED",
    "shipment_details": {
        "recipient": {
            "display_name": "Some Name",
            "email_address": "[email protected]",
            "phone_number": "2222222222",
            "address": {
                "address_line_1": "401 W 56th Street",
                "locality": "New York",
                "administrative_district_level_1": "NY",
                "postal_code": "10019",
                "country": "US"
            }
        },
        "carrier": "UPS",
        "placed_at": "2019-08-06T16:16:26.670Z",
        "shipped_at": "2019-08-09T09:21:24.000Z"
    }
}

API docs are also invalid.

The result is that shipment_details are not accessible in OrderFulfillment object.

Note: order is originating from https://www.weebly.com store.

Managing orders

Hello there,
When will it be possible to manage the orders through Connect API?
Is there a road map that we can track the development progress of this feature?

Getting Tips from the Transaction

I don't think there is any way to separate out tip amount from the tendered value.
I wonder why tip is not part of the tender field?
Any way to get it or any plan to add it to the API?

list_inventory method response does not include link to support pagination

The list_inventory method works on a v1 endpoint that paginates when there are > 1,000 inventoried item variants. The raw endpoint's response includes a header with a link to supply in the subsequent request and retrieve the next batch of results. But the return value of this sdk method only includes an array of V1InventoryEntry objects, and no link, cursor or other value to supply (presumably as the value for the batch_token parameter) in subsequent requests. Please advise if I'm missing something (which is quite possible) or whether pagination isn't actually supported by the list_inventory method (yet).

Inventory

Is managing inventory and products on the roadmap for this SDK?

Catalog Item Variation Docs Misplaced Fields

https://github.com/square/connect-python-sdk/blob/master/docs/CatalogItemVariation.md

The following are fields in list[ItemVariationLocationOverrides] rather than squareconnect.models.catalog_item_variation

track_inventory
inventory_alert_type
inventory_alert_threshold

Source: https://connect.squareup.com/v2/catalog/list?types=item_variation

{
"type": "ITEM_VARIATION",
"id": "somelongid",
"updated_at": "2018-11-07T00:12:19.849Z",
"version": 1541549539849,
"is_deleted": false,
"catalog_v1_ids": [
{
"catalog_v1_id": "somelongerid",
"location_id": "somelocationid"
}
],
"present_at_all_locations": true,
"item_variation_data": {
"item_id": "anotherlongid",
"name": "FTW - Navy",
"sku": "",
"ordinal": 4,
"pricing_type": "FIXED_PRICING",
"price_money": {
"amount": 2200,
"currency": "USD"
},
"location_overrides": [
{
"location_id": "somelocationid",
"track_inventory": false,
"inventory_alert_type": "NONE",
"inventory_alert_threshold": 0
},
{
"location_id": "somelocationid",
"track_inventory": false,
"inventory_alert_type": "NONE",
"inventory_alert_threshold": 0
}
],
"service_duration": 0
}
},

search_orders fails with uids greater than 60 characters.

When using search_orders, occasionally a response will have uids larger than 60 characters and will cause the sdk to throw a ValueError:

ValueError: Invalid value for 'uid', length must be less than '60'

Doing a manual API request with a problem order id shows that some returns seem to have uids in a different format greater than 60 characters, for example:

"uid": "AC1BA2CF-5C0C-4F2F-B92D-089ABFBED686:8ff2caa9-5c08-467a-a54c-a0c0eccee83c"

getbatch_token broken in Python 3

I'm opening this issue in reference to an existing one (i.e., issue #53), since the two are technically only tangentially related and this may increase the visibility of an easy fix.

Long story short, batch_tokens functionality is broken in certain V1 endpoints when using Python 3 due to the deprecation of has_key() in Python 3. A simple change to getbatch_token in rest.py resolves it, as pointed out by @MHova (see below). As it currently stands, the "Pagination of V1 Endpoints" example in the readme fails in Python 3 with the error:

python: 'dict' object has no attribute 'has_key'

The relevant comment and quote from issue #53 appear below:

1. Great writeup @cschweiger. One nit: I think `has_key()` was removed in Python3 in favor of `in` so some adjustments will have to be made to `if parameters.has_key('batch_token'):`.

2. Any movement on this issue, admins? This seems like a pretty big and easily-solvable problem. I'm surprised nobody else has chimed in on this.

Regarding @MHova's point 1, I ran into this issue as well and implemented the simple fix you suggested for Python 3 compatibility (i.e., in vs. has_key):

def getbatch_token(self):
        link_header = self.getheader('Link')
        if link_header != None:
            match = re.match("^<([^>]+)>;rel='next'$", link_header)
            if match != None:
                next_url = match.group(1)
                parsed_url = urlparse(next_url)
                parameters = parse_qs(parsed_url.query)
                if 'batch_token' in parameters:
                    return parameters['batch_token'][0]
return None

Originally posted by @davedgd in #53 (comment)

documentation typo

There is a typo here:

from squareconnect.apis.transaction_api import TransactionApi

It should be: (with an s)

from squareconnect.apis.transactions_api import TransactionsApi

Authentication issue in latest versions

Using the latest version I get the following error when trying to submit a checkout. The calling code hasn't changed recently, and if I pin my dependency at squareconnect==2.20180712.1 then it works normally.

This appears to be related to the changes in: #70

HTTP response body: {"errors":[{"category":"AUTHENTICATION_ERROR","code":"UNAUTHORIZED","detail":"The `Authorization` http header of your request was malformed. The header value is expected to be of the format \"Bearer TOKEN\" (without quotation marks), where TOKEN is to be replaced with your access token (e.g. \"Bearer ABC123def456GHI789jkl0\"). For more information, see https://docs.connect.squareup.com/api/connect/v2/#requestandresponseheaders. If you are seeing this error message while using one of our officially supported SDKs, please report this to [email protected]."}]}

calling code:

squareconnect.configuration.access_token = 'XXXXX'
square = CheckoutApi()
ch_response = square.create_checkout(SQUARE_LOCATION_ID, ch_request)

ValueError raised when setting Money amount to 0

There is a None check in the Money.amount() setter. However, the check is incorrect. It should be a x is None instead of not x.

https://github.com/square/connect-python-sdk/blob/e7aa929/squareconnect/models/money.py#L73

if not amount:
    raise ValueError("Invalid value for `amount`, must not be `None`")
if amount is None:
    raise ValueError("Invalid value for `amount`, must not be `None`")

My use case that triggered this was when creating an Order, the client library was failing to parse the returned response from Square, probably at the tax and discount fields, as I did not apply any of those to my order.

Serialize AnyApiResponse to Dict / List

I'm facing a fancy issue. I need to serialize AnyApiReponse to Dict or List, and if I use response.__dict__ I get something hardly readable, like {'swagger_types': ... }.

Is there any way to properly serialize response objects?

renew token example

The docs don't explain how to avoid a "missing authorization header" error from the renew_token function. I figured it out by reading source code. Here's an example of how to set that header (this should be in the docs but isn't):

from squareconnect.models.renew_token_request import RenewTokenRequest
from squareconnect.apis.o_auth_api import OAuthApi
from squareconnect.api_client import ApiClient

oAuthApi=OAuthApi(ApiClient(header_name="Authorization", header_value="Client %s"%YOUR_APP_SECRET))
res=oAuthApi.renew_token(client_id=YOUR_APP_ID,
                             body=RenewTokenRequest(access_token=ACCESS_TOKEN_TO_RENEW))
print res.access_token
print res.expires_at

Regen model to spec

Getting the following error in trying to run the sandbox code:

File "/home/ec2-user/misc/py3env/local/lib/python3.4/site-packages/squareconnect/models/location.py", line 177, in capabilities
    .format(capabilities, allowed_values)
ValueError: Invalid value for `capabilities` (['CREDIT_CARD_PROCESSING']), must be one of ['CREDIT_CARD_PROCESSING']

NOTE: An update was applied to the PHP library a few days back to fix this issue:

square/connect-php-sdk@da05a9c#diff-4345e0819ed3f554767c2d710ba520b1

noted here: https://www.sellercommunity.com/t5/Developers-API/SDK-and-Sandbox-locations-quot-Invalid-value-for-capabilities/m-p/29717

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.