{"id":17949303,"url":"https://github.com/gnikyt/basic_shopify_api","last_synced_at":"2025-06-20T05:35:49.003Z","repository":{"id":47202406,"uuid":"273504950","full_name":"gnikyt/basic_shopify_api","owner":"gnikyt","description":"A sync/async REST and GraphQL client for Shopify API using HTTPX","archived":false,"fork":false,"pushed_at":"2023-07-30T09:25:09.000Z","size":193,"stargazers_count":19,"open_issues_count":2,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-16T13:07:29.391Z","etag":null,"topics":["async","graphql","rest","shopify","shopify-api","sync"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gnikyt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-19T13:49:12.000Z","updated_at":"2024-01-21T17:52:38.000Z","dependencies_parsed_at":"2024-10-29T09:49:14.264Z","dependency_job_id":null,"html_url":"https://github.com/gnikyt/basic_shopify_api","commit_stats":{"total_commits":44,"total_committers":4,"mean_commits":11.0,"dds":0.06818181818181823,"last_synced_commit":"ecb432fc55d1e99c0c3480c27bcad60b045cd25a"},"previous_names":["osiset/basic_shopify_api"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/gnikyt/basic_shopify_api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fbasic_shopify_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fbasic_shopify_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fbasic_shopify_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fbasic_shopify_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gnikyt","download_url":"https://codeload.github.com/gnikyt/basic_shopify_api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fbasic_shopify_api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260890223,"owners_count":23077857,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","graphql","rest","shopify","shopify-api","sync"],"created_at":"2024-10-29T09:16:03.002Z","updated_at":"2025-06-20T05:35:43.990Z","avatar_url":"https://github.com/gnikyt.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# basic_shopify_api\n\n![Tests](https://github.com/osiset/basic_shopify_api/workflows/Package%20Test/badge.svg?branch=master)\n[![Coverage](https://coveralls.io/repos/github/osiset/basic_shopify_api/badge.svg?branch=master)](https://coveralls.io/github/osiset/basic_shopify_api?branch=master)\n[![PyPi version](https://badge.fury.io/py/basic-shopify-api.svg)](https://pypi.org/project/basic-shopify-api)\n\nThis library extends HTTPX and implements a read-to-use sync/async client for REST and GraphQL API calls to Shopify's API.\n\nSupport for:\n\n- [X] Sync and async API calls\n- [X] REST API\n- [X] GraphQL API\n- [X] REST rate limiting\n- [X] GraphQL cost limiting\n- [X] Automatic retries of failed requests\n- [X] Support for Retry-After headers\n- [X] Pre/post action support\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Options Setup](#options)\n- [Session Setup](#session)\n- [REST Usage](#rest-usage)\n- [GraphQL Usage](#graphql-usage)\n- [Pre/Post Actions](#prepost-actions)\n- [Utilities](#utilities)\n- [Development](#development)\n- [Testing](#testing)\n- [Documentation](#documentation)\n- [License](#license)\n\n## Installation\n\n`$ pip install basic-shopify-api`\n\nRequires Python 3.\n\n## Options\n\n`Options()`.\n\nThere are a variety of options to take advantage of.\n\nYou can simply create a new instance to use all default values if you're using public API mode.\n\nOptions available:\n\n- `max_retries` (int), the number of attempts to retry a failed request; default: `2`.\n- `retry_on_status` (list), the list of HTTP status codes to watch for, and retry if found; default: `[429, 502, 503, 504]`.\n- `headers` (dict), the list of headers to send with each request.\n- `time_store` (StateStore), an implementation to store times of requests; default: `TimeMemoryStore`.\n- `cost_store` (StateStore), an implementation to store GraphQL response costs; default: `CostMemoryStore`.\n- `deferrer` (Deferrer), an implementation to get current time and sleep for time; default: `SleepDeferrer`.\n- `rest_limit` (int), the number of allowed REST calls per second; default: `2`.\n- `graphql_limit` (int), the cost allowed per second for GraphQL calls; default: `50`.\n- `rest_pre_actions` (list), a list of pre-callable actions to fire before a REST request.\n- `rest_post_actions` (list), a list of post-callable actions to fire after a REST request.\n- `graphql_pre_actions` (list), a list of pre-callable actions to fire before a GraphQL request.\n- `graphql_post_actions` (list), a list of post-callable actions to fire after a GraphQL request.\n- `version` (str), the API version to use for all requests; default: `2020-04`.\n- `mode` (str), the type of API to use either `public` or `private`; default: `public`.\n\nExample:\n\n```python\nopts = Options()\nopts.version = \"unstable\"\nopts.mode = \"private\"\n```\n\n## Session\n\nCreate 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.\n\n`Session(domain, key, password, secret)`.\n\nFor public access, you will need to fill in:\n\n- `domain`, the full myshopify domain.\n- `password`, the shop's access token.\n- `secret`, the app's secret key.\n\nFor private access, you will need to fill in:\n\n- `domain`, the full myshopify domain.\n- `key`, the shop's key.\n- `password`, the shop's password.\n\nExample:\n\n```python\nfrom basic_shopify_api import Session\nsession = Session(domain=\"john-doe.myshopify.com\", key=\"abc\", password=\"123\")\n```\n\n## REST Usage\n\n`rest(method, path[, params, headers])`.\n\n- `method` (str), being one of `get`, `post`, `put`, or `delete`.\n- `path` (str), being an API path, example: `/admin/api/shop.json`.\n- `params` (dict) (optional), being a dict of query or json data.\n- `headers` (dict) (optional), being a dict of additional headers to pass with the request.\n\n### REST Sync\n\nExample:\n\n```python\nfrom basic_shopify_api import Client\n\nwith Client(sess, opts) as client:\n    shop = client.rest(\"get\", \"/admin/api/shop.json\", {\"fields\": \"name,email\"})\n    print(shop.response)\n    print(shop.body[\"name\"])\n\n    # returns the following:\n    # RestResult(\n    #   response=The HTTPX response object,\n    #   body=A dict of JSON response, or None if errors,\n    #   errors=A dict of error response (if possible), or None for no errors, or the exception error,\n    #   status=The HTTP status code,\n    #   link=A RestLink object of next/previous pagination info,\n    #   retries=Number of retires for the request\n    # )\n```\n\n### REST Async\n\nExample:\n\n```python\nfrom basic_shopify_api import AsyncClient\n\n# ...\n\nasync with AsyncClient(sess, opts) as client:\n    shop = await client.rest(\"get\", \"/admin/api/shop.json\", {\"fields\": \"name,email\"})\n    print(shop.response)\n    print(shop.body[\"name\"])\n\n    # returns the following:\n    # RestResult(\n    #   response=The HTTPX response object,\n    #   body=A dict of JSON response, or None if errors,\n    #   errors=A dict of error response (if possible), or None for no errors, or the exception error,\n    #   status=The HTTP status code,\n    #   link=A RestLink object of next/previous pagination info,\n    #   retries=Number of retires for the request\n    # )\n```\n\n## GraphQL Usage\n\n`graphql(query[, variables])`.\n\n- `query` (str), being the GraphQL query string.\n- `variables` (dict) (optional), being the variables for your query or mutation.\n\n### GraphQL Sync\n\nExample:\n\n```python\nfrom basic_shopify_api import Client\n\n# ...\n\nwith Client(sess, opts) as client:\n    shop = client.graphql(\"{ shop { name } }\")\n    print(shop.response)\n    print(shop.body[\"data\"][\"shop\"][\"name\"])\n\n    # returns the following:\n    # ApiResult(\n    #   response=The HTTPX response object,\n    #   body=A dict of JSON response, or None if errors,\n    #   errors=A dict of error response (if possible), or None for no errors, or the exception error,\n    #   status=The HTTP status code,\n    #   retries=Number of retires for the request,\n    # )\n```\n\n### GraphQL Async\n\nExample:\n\n```python\nfrom basic_shopify_api import AsyncClient\n\n# ...\n\nasync with AsyncClient(sess, opts) as client:\n    shop = await client.graphql(\"{ shop { name } }\")\n    print(shop.response)\n    print(shop.body[\"data\"][\"name\"])\n\n    # returns the following:\n    # ApiResult(\n    #   response=The HTTPX response object,\n    #   body=A dict of JSON response, or None if errors,\n    #   errors=A dict of error response (if possible), or None for no errors, or the exception error,\n    #   status=The HTTP status code,\n    #   link=A RestLink object of next/previous pagination info,\n    #   retries=Number of retires for the request\n    # )\n```\n\n## Pre/Post Actions\n\nTo register a pre or post action for REST or GraphQL, simply append it to your options setup.\n\n```python\nfrom basic_shopify_api import Options, Client\n\ndef say_hello(inst):\n    \"\"\"inst is the current client instance, either Client or AsyncClient\"\"\"\n    print(\"hello\")\n\ndef say_world(inst, result):\n    \"\"\"\n    inst is the current client instance, either Client or AsyncClient.\n    result is either RestResult or GraphQLResult object.\n    \"\"\"\n    print(\"world\")\n\nopts = Options()\nopts.rest_pre_actions = [say_hello]\nopts.rest_post_ations = [say_world]\n\nsess = Session(domain=\"john-doe.myshopify.com\", key=\"abc\", password=\"134\")\n\nwith Client(sess, opts) as client:\n    shop = client.rest(\"get\", \"/admin/api/shop.json\")\n    print(shop)\n    # Output: \"hello\" \"world\" \u003cApiResult\u003e\n```\n\n## Utilities\n\nThis will be expanding, but as of now there are utilities to help verify HMAC for 0Auth/URL, proxy requests, and webhook data.\n\n### 0Auth/URL\n\n```python\nfrom basic_shopify_api.utils import hmac_verify\n\nparams = request.args # some method to get a dict of query params\nverified = hmac_verify(\"standard\", \"secret key\", params)\nprint(f\"Verified? {verified}\")\n```\n\n### Proxy\n\n```python\nfrom basic_shopify_api.utils import hmac_verify\n\nparams = request.args # some method to get a dict of query params\nverified = hmac_verify(\"proxy\", \"secret key\", params)\nprint(f\"Verified? {verified}\")\n```\n\n### Webhook\n\n```python\nfrom basic_shopify_api.utils import hmac_verify\n\nhmac_header = request.headers.get(\"x-shopify-hmac-sha256\") # some method to get the HMAC header\nparams = request.get_data(as_text=True) # some method to get a JSON str of request data\nverified = hmac_verify(\"webhook\", \"secret key\", params, hmac_header)\nprint(f\"Verified? {verified}\")\n```\n\n## Development\n\n`python -m venv env \u0026\u0026 source env/bin/activate`\n\n`python -m pip install -r requirements.txt`\n\n## Testing\n\n`make test`.\n\nFor coverage reports, use `make cover` or `make cover-html`.\n\n## Documentation\n\nSee [this Github page](https://osiset.com/basic_shopify_api/) or view `docs/`.\n\n## License\n\nThis project is released under the MIT [license](https://github.com/osiset/basic_shopify_api/blob/master/LICENSE).\n\n## Misc\n\nUsing PHP? [Check out Basic-Shopify-API](https://github.com/osiset/Basic-Shopify-API).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnikyt%2Fbasic_shopify_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgnikyt%2Fbasic_shopify_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnikyt%2Fbasic_shopify_api/lists"}