Package: fastshopifyapi
FastShopifyApiThis library extends HTTPX and implements a read-to-use sync/async client for REST and GraphQL API calls to Shopify's API.Forked fromosiset/basic_shopify_apiwith the following changes:Renamebasic_shopify_apitoFastShopifyApiUpgrade Shopify API versionFixed some bugsThanks toTyler Kingfor his work.Support for:Sync and async API callsREST APIGraphQL APIREST rate limitingGraphQL cost limitingAutomatic retries of failed requestsSupport for Retry-After headersPre/post action supportTable of ContentsInstallationOptions SetupSession SetupREST UsageGraphQL UsagePre/Post ActionsUtilitiesDevelopmentTestingDocumentationLicenseInstallation$ pip install fastshopifyapiRequires Python 3.OptionsOptions().There are a variety of options to take advantage of.You can simply create a new instance to use all default values if you're using public API mode.Options available:max_retries(int), the number of attempts to retry a failed request; default:2.retry_on_status(list), the list of HTTP status codes to watch for, and retry if found; default:[429, 502, 503, 504].headers(dict), the list of headers to send with each request.time_store(StateStore), an implementation to store times of requests; default:TimeMemoryStore.cost_store(StateStore), an implementation to store GraphQL response costs; default:CostMemoryStore.deferrer(Deferrer), an implementation to get current time and sleep for time; default:SleepDeferrer.rest_limit(int), the number of allowed REST calls per second; default:2.graphql_limit(int), the cost allowed per second for GraphQL calls; default:50.rest_pre_actions(list), a list of pre-callable actions to fire before a REST request.rest_post_actions(list), a list of post-callable actions to fire after a REST request.graphql_pre_actions(list), a list of pre-callable actions to fire before a GraphQL request.graphql_post_actions(list), a list of post-callable actions to fire after a GraphQL request.version(str), the API version to use for all requests; default:2023-10.mode(str), the type of API to use eitherpublicorprivate; default:public.Example:opts=Options()opts.version="unstable"opts.mode="private"SessionCreate a session to use with a client. Depending on if you're accessing the API public or privately, then you will need to fill different values.Session(domain, key, password, secret).For public access, you will need to fill in:domain, the full myshopify domain.password, the shop's access token.secret, the app's secret key.For private access, you will need to fill in:domain, the full myshopify domain.key, the shop's key.password, the shop's password.Example:fromfastshopifyapiimportSessionsession=Session(domain="john-doe.myshopify.com",key="abc",password="123")REST Usagerest(method, path, params, headers]).method(str), being one ofget,post,put, ordelete.path(str), being an API path, example:/admin/api/shop.json.params(dict) (optional), being a dict of query or json data.headers(dict) (optional), being a dict of additional headers to pass with the request.REST SyncExample:fromfastshopifyapiimportClientwithClient(sess,opts)asclient:shop=client.rest("get","/admin/api/shop.json",{"fields":"name,email"})print(shop.response)print(shop.body["name"])# returns the following:# RestResult(#   response=The HTTPX response object,#   body=A dict of JSON response, or None if errors,#   errors=A dict of error response (if possible), or None for no errors, or the exception error,#   status=The HTTP status code,#   link=A RestLink object of next/previous pagination info,#   retries=Number of retires for the request# )REST AsyncExample:fromfastshopifyapiimportAsyncClient# ...asyncwithAsyncClient(sess,opts)asclient:shop=awaitclient.rest("get","/admin/api/shop.json",{"fields":"name,email"})print(shop.response)print(shop.body["name"])# returns the following:# RestResult(#   response=The HTTPX response object,#   body=A dict of JSON response, or None if errors,#   errors=A dict of error response (if possible), or None for no errors, or the exception error,#   status=The HTTP status code,#   link=A RestLink object of next/previous pagination info,#   retries=Number of retires for the request# )GraphQL Usagegraphql(query[, variables]).query(str), being the GraphQL query string.variables(dict) (optional), being the variables for your query or mutation.GraphQL SyncExample:fromfastshopifyapiimportClient# ...withClient(sess,opts)asclient:shop=client.graphql("{ shop { name } }")print(shop.response)print(shop.body["data"]["shop"]["name"])# returns the following:# ApiResult(#   response=The HTTPX response object,#   body=A dict of JSON response, or None if errors,#   errors=A dict of error response (if possible), or None for no errors, or the exception error,#   status=The HTTP status code,#   retries=Number of retires for the request,# )GraphQL AsyncExample:fromfastshopifyapiimportAsyncClient# ...asyncwithAsyncClient(sess,opts)asclient:shop=awaitclient.graphql("{ shop { name } }")print(shop.response)print(shop.body["data"]["name"])# returns the following:# ApiResult(#   response=The HTTPX response object,#   body=A dict of JSON response, or None if errors,#   errors=A dict of error response (if possible), or None for no errors, or the exception error,#   status=The HTTP status code,#   link=A RestLink object of next/previous pagination info,#   retries=Number of retires for the request# )Pre/Post ActionsTo register a pre or post action for REST or GraphQL, simply append it to your options setup.fromfastshopifyapiimportOptions,Clientdefsay_hello(inst):"""inst is the current client instance, either Client or AsyncClient"""print("hello")defsay_world(inst,result):"""inst is the current client instance, either Client or AsyncClient.result is either RestResult or GraphQLResult object."""print("world")opts=Options()opts.rest_pre_actions=[say_hello]opts.rest_post_ations=[say_world]sess=Session(domain="john-doe.myshopify.com",key="abc",password="134")withClient(sess,opts)asclient:shop=client.rest("get","/admin/api/shop.json")print(shop)# Output: "hello" "world" <ApiResult>UtilitiesThis will be expanding, but as of now there are utilities to help verify HMAC for 0Auth/URL, proxy requests, and webhook data.0Auth/URLfromfastshopifyapi.utilsimporthmac_verifyparams=request.args# some method to get a dict of query paramsverified=hmac_verify("standard","secret key",params)print(f"Verified?{verified}")Proxyfromfastshopifyapi.utilsimporthmac_verifyparams=request.args# some method to get a dict of query paramsverified=hmac_verify("proxy","secret key",params)print(f"Verified?{verified}")Webhookfromfastshopifyapi.utilsimporthmac_verifyhmac_header=request.headers.get("x-shopify-hmac-sha256")# some method to get the HMAC headerparams=request.get_data(as_text=True)# some method to get a JSON str of request dataverified=hmac_verify("webhook","secret key",params,hmac_header)print(f"Verified?{verified}")Developmentpython -m venv env && source env/bin/activatepython -m pip install -r requirements.txtTestingmake test.For coverage reports, usemake coverormake cover-html.DocumentationSeethis Github pageor viewdocs/.LicenseThis project is released under the MITlicense.MiscUsing PHP?Check out Basic-Shopify-API.