Ad

Sending Multiple POST Requests To The Same Session Using Threading

I am currently making a script which will add to cart and checkout items on e-commerce websites run on the shopify platform

I'm trying to speed up the process by running the add to cart method on multiple threads. My add to cart function looks like this:

def add_to_cart(keywords,size,session,quantity=1):
     ...

where keywords is the list of strings so we can parse and find the correct item, and session is the a new session from the requests module. The function first parses through the sitemap, finding the unique product ID, then sends a post request to the session variable to add said item to cart.

However, when I run the script using threads to add multiple items to cart, i only see one of the items in the cart. Why isn't this working? Would I need to lock + unlock the session variable and send the POST request one by one?

Here's the code that I am running:

from ATC import *
from checkout import *
import requests
import time
import threading
from bs4 import BeautifulSoup

session = requests.Session()
init = time.time()

t1 = threading.Thread(target=add_to_cart, args=(['carabiner', 'black'], 'one size', session, 1,))
t2 = threading.Thread(target=add_to_cart, args=(['drury', '8.2'], '8.2', session, 1,))
t1.start()
t2.start()
t1.join()
t2.join()
now = time.time()
print("Time Taken: " + str(format(now-init, '.3g')) + 's')
Ad

Answer

From my experience, if you hit Shopify with multiple cart changes at the same time, only one will go through. My guess is that Shopify handles the cart something like this:

At time 0 we have our initial cart - call it cart0

At time t, we submit n simultaneous requests to add/update/change the cart

Request 0: take cart0 and apply request, return result Request 1: take cart0 and apply request, return result ... Request n: take cart0 and apply request, return result

This seems consistent with the cart return values that I got when I tested multiple requests at the same time - each callback function would trigger with a cart that had a single change applied.

I've found two ways to deal with this limitation. The first is to make sure the requests are chained so that we wait for one to finish before making the next - effectively turning the asynchronous requests into synchronous ones. Not the best for speed.

The other method only works if we don't have line item properties to worry about: combining all the additions/changes into one call to /cart/update.js, passing the variant IDs and desired quantities all at once - see https://help.shopify.com/themes/development/getting-started/using-ajax-api#update-cart for examples. If you don't have line properties to worry about, changing your single-line additions into one big update will be a significant speed and reliability increase.

Ad
source: stackoverflow.com
Ad