How do I connect Foundry to Shopify?

I’m going to share a quick tutorial below. It will tackle batch reads using the connector built into Foundry and batch writes using a python external transform. The external transform should be fairly easy to adapt to python external functions so that you can use them live through the Ontology if you want to.

One thing this doesn’t tackle is using OAuth for external calls to allow each user of your foundry built applicaiton to authenticate as themselves, which is something you may want to explore using Foundry’s Outbound Applications (though they are currently limited to Webhooks only, so you won’t be able to use the Spotify Python library).

For any sort of batch processing we generally recommend using token based auth anyway.

Ok here we go:

Setting up the source

  1. Create a new Shopify connection in Data Connection.
  2. Follow the instructions here to generate the appropriate access token.
  3. Fill in your shop URL and and Access Token. Foundry will suggest an Egress policy - use it.
  4. You’re done! Now you can explore the Shopify source and setup table syncs.

Setting External Transforms

  1. Setup a new python repository and follow these instructions to make it an external source-based transform. Make sure you enable Code Rpositories imports on the source (and Enable exports if you want to use other datasets as inputs).
  2. Import the previously created Source.
  3. Add the Shopify python library to the repository.
  4. Now you can write your transform. By importing the source into the repo you autoamtically set the same egress policy as teh source and get access to the source’s secrets. Look at some sample code below:
from transforms.api import transform, Output
from transforms.external.systems import external_systems, Source

import shopify


# using https://github.com/Shopify/shopify_python_api
@external_systems(
    shopify_connector_source=Source(
        "ri.magritte..source.b27bab4f-05e0-4198-ba62-8ae8174c4f01"
    )
)
@transform(
    output=Output("ri.foundry.main.dataset.76df0de3-726d-4f3d-bfd6-eb21c36892dd")
)
def compute(shopify_connector_source, output):
    TOKEN = shopify_connector_source.get_secret(
        "jdbcEncryptedPropertybb2759ed701a44b8be46a2751104e79b"
    )
    SHOP_URL = "219600-56.myshopify.com/"
    API_VERSION = "2024-07"

    session = shopify.Session(SHOP_URL, API_VERSION, TOKEN)
    shopify.ShopifyResource.activate_session(session)

    product = shopify.Product() 
    product.title = "Shopify Logo T-Shirt"
    product.save()
    shopify.ShopifyResource.clear_session()

    return

The two caveats here are:

  • The secret name is not very descriptive if you use a foundry-provided source instead of custom rest source.
  • You don’t get access to the URL parameter, only the secrets. Hence SHOP_URL variable in the code above.

Despite those caveats I think it’s a cleaner solution than maintaining two sources.

3 Likes