kurumera 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. kurumera/__init__.py +66 -0
  2. kurumera/_generated/__init__.py +122 -0
  3. kurumera/_generated/alias_tools.py +65 -0
  4. kurumera/_generated/analytics_tools.py +169 -0
  5. kurumera/_generated/blog_tools.py +100 -0
  6. kurumera/_generated/branch_tools.py +91 -0
  7. kurumera/_generated/branding_tools.py +98 -0
  8. kurumera/_generated/campaign_tools.py +103 -0
  9. kurumera/_generated/cart_tools.py +58 -0
  10. kurumera/_generated/collection_tools.py +189 -0
  11. kurumera/_generated/commercial_tools.py +161 -0
  12. kurumera/_generated/content_access.py +82 -0
  13. kurumera/_generated/content_delete.py +49 -0
  14. kurumera/_generated/crm_file_tools.py +118 -0
  15. kurumera/_generated/crm_tools.py +1118 -0
  16. kurumera/_generated/currency_tools.py +72 -0
  17. kurumera/_generated/customer_tools.py +71 -0
  18. kurumera/_generated/discount_tools.py +45 -0
  19. kurumera/_generated/doc_tools.py +102 -0
  20. kurumera/_generated/email_tools.py +236 -0
  21. kurumera/_generated/faq_tools.py +50 -0
  22. kurumera/_generated/finance_tools.py +173 -0
  23. kurumera/_generated/forecast_tools.py +211 -0
  24. kurumera/_generated/form_tools.py +64 -0
  25. kurumera/_generated/gift_card_tools.py +60 -0
  26. kurumera/_generated/inbox_tools.py +256 -0
  27. kurumera/_generated/inventory_tools.py +156 -0
  28. kurumera/_generated/invoice_tools.py +259 -0
  29. kurumera/_generated/media_library_tools.py +114 -0
  30. kurumera/_generated/media_tools.py +188 -0
  31. kurumera/_generated/merge_tools.py +148 -0
  32. kurumera/_generated/merged_tools.py +249 -0
  33. kurumera/_generated/migration_tools.py +126 -0
  34. kurumera/_generated/nav_tools.py +58 -0
  35. kurumera/_generated/notification_tools.py +45 -0
  36. kurumera/_generated/order_tools.py +245 -0
  37. kurumera/_generated/page_locale_tools.py +96 -0
  38. kurumera/_generated/page_tools.py +106 -0
  39. kurumera/_generated/pagebuilder_authoring_tools.py +178 -0
  40. kurumera/_generated/pagebuilder_component_tools.py +75 -0
  41. kurumera/_generated/pagebuilder_visual_tools.py +42 -0
  42. kurumera/_generated/pos_tools.py +54 -0
  43. kurumera/_generated/product_tools.py +248 -0
  44. kurumera/_generated/review_tools.py +41 -0
  45. kurumera/_generated/site_gen_tools.py +115 -0
  46. kurumera/_generated/social_tools.py +165 -0
  47. kurumera/_generated/store_tools.py +46 -0
  48. kurumera/_generated/translation_tools.py +67 -0
  49. kurumera/_generated/webhook_tools.py +58 -0
  50. kurumera/_transport.py +227 -0
  51. kurumera/_version.py +1 -0
  52. kurumera/client.py +266 -0
  53. kurumera/credentials.py +146 -0
  54. kurumera/errors.py +264 -0
  55. kurumera/py.typed +0 -0
  56. kurumera/registry.json +12990 -0
  57. kurumera/registry.py +89 -0
  58. kurumera/types.py +199 -0
  59. kurumera-0.1.0.dist-info/METADATA +205 -0
  60. kurumera-0.1.0.dist-info/RECORD +62 -0
  61. kurumera-0.1.0.dist-info/WHEEL +4 -0
  62. kurumera-0.1.0.dist-info/licenses/LICENSE +21 -0
kurumera/__init__.py ADDED
@@ -0,0 +1,66 @@
1
+ """
2
+ kurumera - drive a Kurumera store from Python.
3
+
4
+ pip install kurumera
5
+
6
+ from kurumera import Kurumera
7
+ km = Kurumera() # KURUMERA_API_KEY from the environment
8
+ km.create_product(title="Badam 500g")
9
+
10
+ Every method is one of the platform's MCP tools, under the same name, reaching
11
+ the same authenticated endpoint. Nothing here decides what you are allowed to
12
+ do: the store, the capabilities and the limits all come from your credential,
13
+ checked server-side exactly as they are for any other client.
14
+ """
15
+ from __future__ import annotations
16
+
17
+ from ._version import __version__
18
+ from .client import Kurumera
19
+ from .credentials import DEFAULT_MCP_URL
20
+ from .errors import (
21
+ AccountError,
22
+ AuthError,
23
+ AuthFailed,
24
+ AuthRequired,
25
+ ConfirmationRequired,
26
+ DestructiveBlockedError,
27
+ InvalidArguments,
28
+ KurumeraConfigError,
29
+ KurumeraConnectionError,
30
+ KurumeraError,
31
+ KurumeraProtocolError,
32
+ NoTenant,
33
+ PermissionDenied,
34
+ RateLimited,
35
+ ReadOnlyModeError,
36
+ ServerError,
37
+ SubscriptionInactive,
38
+ TenantCancelled,
39
+ TenantInactive,
40
+ TenantMismatch,
41
+ TenantPendingApproval,
42
+ ToolCallError,
43
+ ToolNotFound,
44
+ UserInactive,
45
+ UserNotFound,
46
+ )
47
+ from .registry import registry_hash as _registry_hash
48
+ from .registry import tool_count as _tool_count
49
+ from .types import UNSET, Annotations, ToolImage, ToolInfo, ToolResult
50
+
51
+ #: Which tool registry this package was generated from. Report it in a bug.
52
+ REGISTRY_HASH = _registry_hash()
53
+ REGISTRY_TOOL_COUNT = _tool_count()
54
+
55
+ __all__ = [
56
+ "Kurumera",
57
+ "ToolResult", "ToolImage", "ToolInfo", "Annotations", "UNSET",
58
+ "DEFAULT_MCP_URL", "REGISTRY_HASH", "REGISTRY_TOOL_COUNT", "__version__",
59
+ "KurumeraError", "KurumeraConfigError", "KurumeraConnectionError",
60
+ "KurumeraProtocolError", "AuthError", "AuthRequired", "AuthFailed",
61
+ "UserNotFound", "TenantMismatch", "AccountError", "UserInactive", "NoTenant",
62
+ "TenantInactive", "TenantPendingApproval", "TenantCancelled",
63
+ "SubscriptionInactive", "ServerError", "ReadOnlyModeError",
64
+ "DestructiveBlockedError", "ToolCallError", "ToolNotFound",
65
+ "InvalidArguments", "PermissionDenied", "RateLimited", "ConfirmationRequired",
66
+ ]
@@ -0,0 +1,122 @@
1
+ """
2
+ GENERATED by `python manage.py generate_python_sdk`. Do not edit.
3
+
4
+ Every method is one MCP tool, under the tool's own name, with the tool's own
5
+ documentation. Optional arguments default to UNSET rather than None because the
6
+ server rejects an explicit null for them - see the generator's module docstring.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, Generic, TypeVar
11
+
12
+ from ..types import UNSET, _Unset
13
+
14
+ R = TypeVar("R")
15
+
16
+
17
+ class _ToolBase(Generic[R]):
18
+ """Supplies `_invoke`. The client decides whether R is a result or a future."""
19
+
20
+ def _invoke(self, name: str, args: dict[str, Any]) -> R: # pragma: no cover
21
+ raise NotImplementedError
22
+
23
+
24
+ from .alias_tools import AliasTools # noqa: E402
25
+ from .analytics_tools import AnalyticsTools # noqa: E402
26
+ from .blog_tools import BlogTools # noqa: E402
27
+ from .branch_tools import BranchTools # noqa: E402
28
+ from .branding_tools import BrandingTools # noqa: E402
29
+ from .campaign_tools import CampaignTools # noqa: E402
30
+ from .cart_tools import CartTools # noqa: E402
31
+ from .collection_tools import CollectionTools # noqa: E402
32
+ from .commercial_tools import CommercialTools # noqa: E402
33
+ from .content_access import ContentAccessTools # noqa: E402
34
+ from .content_delete import ContentDeleteTools # noqa: E402
35
+ from .crm_file_tools import CrmFileTools # noqa: E402
36
+ from .crm_tools import CrmTools # noqa: E402
37
+ from .currency_tools import CurrencyTools # noqa: E402
38
+ from .customer_tools import CustomerTools # noqa: E402
39
+ from .discount_tools import DiscountTools # noqa: E402
40
+ from .doc_tools import DocTools # noqa: E402
41
+ from .email_tools import EmailTools # noqa: E402
42
+ from .faq_tools import FaqTools # noqa: E402
43
+ from .finance_tools import FinanceTools # noqa: E402
44
+ from .forecast_tools import ForecastTools # noqa: E402
45
+ from .form_tools import FormTools # noqa: E402
46
+ from .gift_card_tools import GiftCardTools # noqa: E402
47
+ from .inbox_tools import InboxTools # noqa: E402
48
+ from .inventory_tools import InventoryTools # noqa: E402
49
+ from .invoice_tools import InvoiceTools # noqa: E402
50
+ from .media_library_tools import MediaLibraryTools # noqa: E402
51
+ from .media_tools import MediaTools # noqa: E402
52
+ from .merge_tools import MergeTools # noqa: E402
53
+ from .merged_tools import MergedTools # noqa: E402
54
+ from .migration_tools import MigrationTools # noqa: E402
55
+ from .nav_tools import NavTools # noqa: E402
56
+ from .notification_tools import NotificationTools # noqa: E402
57
+ from .order_tools import OrderTools # noqa: E402
58
+ from .page_locale_tools import PageLocaleTools # noqa: E402
59
+ from .page_tools import PageTools # noqa: E402
60
+ from .pagebuilder_authoring_tools import PagebuilderAuthoringTools # noqa: E402
61
+ from .pagebuilder_component_tools import PagebuilderComponentTools # noqa: E402
62
+ from .pagebuilder_visual_tools import PagebuilderVisualTools # noqa: E402
63
+ from .pos_tools import PosTools # noqa: E402
64
+ from .product_tools import ProductTools # noqa: E402
65
+ from .review_tools import ReviewTools # noqa: E402
66
+ from .site_gen_tools import SiteGenTools # noqa: E402
67
+ from .social_tools import SocialTools # noqa: E402
68
+ from .store_tools import StoreTools # noqa: E402
69
+ from .translation_tools import TranslationTools # noqa: E402
70
+ from .webhook_tools import WebhookTools # noqa: E402
71
+
72
+
73
+ class GeneratedTools(
74
+ AliasTools[R],
75
+ AnalyticsTools[R],
76
+ BlogTools[R],
77
+ BranchTools[R],
78
+ BrandingTools[R],
79
+ CampaignTools[R],
80
+ CartTools[R],
81
+ CollectionTools[R],
82
+ CommercialTools[R],
83
+ ContentAccessTools[R],
84
+ ContentDeleteTools[R],
85
+ CrmFileTools[R],
86
+ CrmTools[R],
87
+ CurrencyTools[R],
88
+ CustomerTools[R],
89
+ DiscountTools[R],
90
+ DocTools[R],
91
+ EmailTools[R],
92
+ FaqTools[R],
93
+ FinanceTools[R],
94
+ ForecastTools[R],
95
+ FormTools[R],
96
+ GiftCardTools[R],
97
+ InboxTools[R],
98
+ InventoryTools[R],
99
+ InvoiceTools[R],
100
+ MediaLibraryTools[R],
101
+ MediaTools[R],
102
+ MergeTools[R],
103
+ MergedTools[R],
104
+ MigrationTools[R],
105
+ NavTools[R],
106
+ NotificationTools[R],
107
+ OrderTools[R],
108
+ PageLocaleTools[R],
109
+ PageTools[R],
110
+ PagebuilderAuthoringTools[R],
111
+ PagebuilderComponentTools[R],
112
+ PagebuilderVisualTools[R],
113
+ PosTools[R],
114
+ ProductTools[R],
115
+ ReviewTools[R],
116
+ SiteGenTools[R],
117
+ SocialTools[R],
118
+ StoreTools[R],
119
+ TranslationTools[R],
120
+ WebhookTools[R],
121
+ ):
122
+ """Every tool the platform exposed when this package was built."""
@@ -0,0 +1,65 @@
1
+ """
2
+ GENERATED by `python manage.py generate_python_sdk`. Do not edit.
3
+
4
+ Tools from mcp_server/tools/alias_tools.py.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, TypeVar
9
+
10
+ from ..types import UNSET, _Unset
11
+ from . import _ToolBase
12
+
13
+ R = TypeVar("R")
14
+
15
+
16
+ class AliasTools(_ToolBase[R]):
17
+ def add_search_aliases(self, content_type: str, item_id: str, terms: list[Any], *, confirm: bool | _Unset = UNSET) -> R:
18
+ """
19
+ Requires confirm=True.
20
+
21
+ Make a product findable by extra words shoppers actually type.
22
+
23
+ Good aliases: local names ("Motia" for jasmine), transliterations
24
+ ("موتیا"), spelling variants ("Motiya"), common phrases ("motia ka poda"),
25
+ and old names customers still use.
26
+
27
+ Bad aliases: generic words like "plant" or "gift" — they make the product
28
+ match searches it has no business appearing in, which pushes down results
29
+ that genuinely match.
30
+
31
+ Aliases are invisible on the storefront and take effect immediately. They
32
+ change what search finds, never what a shopper reads.
33
+
34
+ Omitted arguments are not sent; the store applies its own defaults: confirm=False.
35
+ """
36
+ return self._invoke("add_search_aliases", {"content_type": content_type, "item_id": item_id, "terms": terms, "confirm": confirm})
37
+
38
+ def list_search_aliases(self, *, content_type: str | _Unset = UNSET, item_id: str | _Unset = UNSET) -> R:
39
+ """
40
+ Read-only.
41
+
42
+ The extra search terms attached to a product (or the whole store).
43
+
44
+ Omit `item_id` for a store-wide view — useful for spotting which products
45
+ have no local-language terms yet and would therefore be invisible to a
46
+ shopper searching in Urdu or Roman Urdu.
47
+
48
+ Omitted arguments are not sent; the store applies its own defaults: content_type='product'.
49
+ """
50
+ return self._invoke("list_search_aliases", {"content_type": content_type, "item_id": item_id})
51
+
52
+ def remove_search_aliases(self, content_type: str, item_id: str, terms: list[Any], *, confirm: bool | _Unset = UNSET) -> R:
53
+ """
54
+ DESTRUCTIVE - removes, overwrites or makes something irreversibly live.
55
+ Requires confirm=True.
56
+
57
+ Remove search terms from a product.
58
+
59
+ Use when an alias is pulling the product into searches it shouldn't match.
60
+ Removing one only narrows what search finds — it never hides the product
61
+ itself.
62
+
63
+ Omitted arguments are not sent; the store applies its own defaults: confirm=False.
64
+ """
65
+ return self._invoke("remove_search_aliases", {"content_type": content_type, "item_id": item_id, "terms": terms, "confirm": confirm})
@@ -0,0 +1,169 @@
1
+ """
2
+ GENERATED by `python manage.py generate_python_sdk`. Do not edit.
3
+
4
+ Tools from mcp_server/tools/analytics_tools.py.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, TypeVar
9
+
10
+ from ..types import UNSET, _Unset
11
+ from . import _ToolBase
12
+
13
+ R = TypeVar("R")
14
+
15
+
16
+ class AnalyticsTools(_ToolBase[R]):
17
+ def generate_business_report(self, report_type: str, *, baseline_from: str | _Unset = UNSET, baseline_label: str | _Unset = UNSET, baseline_to: str | _Unset = UNSET, compare: bool | _Unset = UNSET, date_from: str | _Unset = UNSET, date_to: str | _Unset = UNSET, days: int | _Unset = UNSET, theme: str | _Unset = UNSET) -> R:
18
+ """
19
+ Read-only.
20
+
21
+ A whole branded report in one call — ordered sections, each with its
22
+ numbers, its chart and the reference that traces it to the call behind it.
23
+
24
+ Enough to assemble a deck without asking a second question and without
25
+ reading a pixel.
26
+
27
+ report_type:
28
+ weekly_management How the week went, sales, what sold, payment states.
29
+ merchant_performance Headline, gross-to-net, best sellers, customers.
30
+ agency_client Results, visitors, sources, visit-to-purchase.
31
+ product_review By product, by units, stock on hand, the funnel.
32
+ investor_evidence Headline, gross-to-net, revenue, growth — as
33
+ EVIDENCE charts, provenance stamped on each image.
34
+ bank_evidence Gross-to-net, payment states, tax, refunds — also
35
+ evidence charts.
36
+ enterprise_case_study Headline, growth, customers, what sells — as
37
+ evidence charts, because a prospect handed a
38
+ growth figure cannot check it otherwise.
39
+ migration Before and after, against a baseline YOU state.
40
+ Needs baseline_from, baseline_to and
41
+ baseline_label; see below.
42
+
43
+ BEFORE/AFTER (migration)
44
+ baseline_from/_to The window the store traded in BEFORE the change,
45
+ YYYY-MM-DD. Must end before the reported period
46
+ opens — an overlapping baseline counts the same
47
+ trading on both sides and is refused, not caveated.
48
+ baseline_label What that window WAS, in your words: "trading on the
49
+ old platform", "the quarter before launch". Required,
50
+ because a reader shown two numbers and told nothing
51
+ about the first one has not been shown a comparison.
52
+
53
+ Every section runs TWICE, once per window, through this same tool — so
54
+ before and after are one definition, and each half carries its own
55
+ reference and its own stamped chart. Unequal window lengths are allowed
56
+ and stated; a baseline in which Kurumera recorded no orders at all is
57
+ called out, because rendering it as zero turns a migration date into
58
+ growth.
59
+
60
+ THIS COMPUTES NOTHING. Every figure comes from `get_report` and every
61
+ colour from the brand kit, so a section you could not read directly you
62
+ cannot read here either: the finance scope and the identity redaction apply
63
+ exactly as they do to a direct call.
64
+
65
+ A section that cannot be produced is MARKED, never filled. Check
66
+ `summary.complete` and `summary.warnings` before presenting the report, and
67
+ say plainly which parts are missing rather than working around the hole —
68
+ a gap filled with a plausible number is the one failure that makes a report
69
+ dangerous rather than merely incomplete.
70
+
71
+ Returns:
72
+ JSON: { report_type, brand: {...}, sections: [ { report, title,
73
+ available, data, chart, reference, reason } ],
74
+ summary: { sections_requested, sections_available, complete,
75
+ warnings } }
76
+
77
+ Omitted arguments are not sent; the store applies its own defaults: compare=True, days=30, theme='light'.
78
+ """
79
+ return self._invoke("generate_business_report", {"report_type": report_type, "baseline_from": baseline_from, "baseline_label": baseline_label, "baseline_to": baseline_to, "compare": compare, "date_from": date_from, "date_to": date_to, "days": days, "theme": theme})
80
+
81
+ def get_report(self, report: str, *, city: str | _Unset = UNSET, compare: bool | _Unset = UNSET, country: str | _Unset = UNSET, date_from: str | _Unset = UNSET, date_to: str | _Unset = UNSET, days: int | _Unset = UNSET, group_by: str | _Unset = UNSET, limit: int | _Unset = UNSET, location_id: str | _Unset = UNSET, max_cohorts: int | _Unset = UNSET, render: str | _Unset = UNSET, theme: str | _Unset = UNSET) -> R:
82
+ """
83
+ Read-only.
84
+
85
+ Every analytics and reporting read for this store, selected by `report`.
86
+
87
+ Window: `days` (default 30, inclusive of today) OR explicit `date_from` /
88
+ `date_to` (YYYY-MM-DD). The extra args apply only to the reports that name
89
+ them below; the rest are ignored.
90
+
91
+ Every response carries `_meta` alongside the report's own keys: the store,
92
+ its CURRENCY and TIMEZONE, the exact window, when it was generated, and a
93
+ "Generated from Kurumera" source line. Quote the currency whenever you
94
+ quote a figure — "16,084" on its own is not a fact anybody can check.
95
+
96
+ `compare=True` adds `_meta.comparison`: the same report over the span of
97
+ equal length immediately before, so a week can be read against the week
98
+ before it. Refused for inventory_valuation, live_snapshot and rfm, which
99
+ describe a moment rather than a span.
100
+
101
+ Reports that STATE MONEY — sales_breakdown, financial_summary, tax,
102
+ refunds, inventory_valuation, pos_till, branch_sales — need `read_orders`
103
+ as well as `read_analytics`. Trading reports (summary, sales,
104
+ revenue_by_day, top_products) need only the latter. Each money report
105
+ returns a `definitions` block saying what its figures mean; quote the
106
+ definition alongside the number.
107
+
108
+ Customer identities are REDACTED unless you also hold the `read_customers`
109
+ capability: names become "Customer 1", contact details are emptied, and
110
+ every aggregate — spend, order counts, segments, scores — is untouched.
111
+ `_meta.redaction` says which happened (`identities`, `none`, or
112
+ `not_applicable`). Do not present a redacted name as if it were real.
113
+
114
+ `render='evidence'` draws the same chart with the store, the exact window,
115
+ the timezone, the currency, the generation time and the traceable reference
116
+ stamped ON the image — for an audit or a file, where the chart is handed
117
+ over on its own and its context cannot live in a response somebody else is
118
+ holding.
119
+
120
+ `render='svg'` adds `chart`: the same numbers drawn as a 1920×1080 SVG,
121
+ sized and labelled for a 16:9 slide and carrying its own period and
122
+ currency caption. `theme='dark'` draws it for a dark deck. The SVG IS the
123
+ editable artefact — open it in any vector tool, or restyle it from the
124
+ structured data returned beside it. Only reports with a real chart form
125
+ render: sales, revenue_by_day, orders_by_day, product_performance,
126
+ top_products and summary. Anything else is refused rather than forced into
127
+ a shape it does not have.
128
+
129
+ report:
130
+ summary Revenue, orders, AOV, new customers.
131
+ sales Revenue/orders over time. Set group_by=day|week|month.
132
+ orders_by_day Daily order counts.
133
+ revenue_by_day Daily revenue totals.
134
+ top_products Best sellers by units. Set limit.
135
+ product_performance Units/revenue/orders. Set limit, and
136
+ group_by=product|variant|category. `variant`
137
+ answers which SIZE sells, which the product row
138
+ averages away. No margin column: unit costs are
139
+ recorded on under 1% of line items, so one would
140
+ be null for almost every row.
141
+ sales_breakdown Gross → discounts → refunds → NET SALES, plus tax,
142
+ shipping and total charged. Every definition is in
143
+ the response; tax and shipping are stated BESIDE
144
+ net sales, never inside it. Check `reconciles`
145
+ before quoting the figures.
146
+ financial_summary Financial + fulfillment status breakdown.
147
+ tax Tax collected.
148
+ refunds Refunds issued.
149
+ inventory_valuation Stock valuation at cost and retail. No window.
150
+ live_snapshot Active visitors, recent events, live orders. No window.
151
+ traffic Sessions / pageviews / visitors trend.
152
+ acquisition Referrers / channels / UTM sources.
153
+ geography Sales + sessions by country/city. Filter country=, city=.
154
+ behavior Top pages, entry/exit, engagement. Set limit.
155
+ product_behavior Per-product view to cart to purchase funnel. Set limit.
156
+ conversion_funnel Storewide visit to view to cart to purchase.
157
+ checkout_funnel Checkout steps started through completed.
158
+ customer_acquisition New vs returning customers.
159
+ cohorts Retention by first-order month. Set max_cohorts.
160
+ rfm RFM segments. No window.
161
+ search Top on-site searches + no-results. Set limit.
162
+ branch_sales Sales per branch. Filter location_id (see list_locations).
163
+ pos_till POS takings by tender. Filter location_id.
164
+
165
+ Returns: JSON for the chosen report.
166
+
167
+ Omitted arguments are not sent; the store applies its own defaults: compare=False, days=30, group_by='day', limit=20, max_cohorts=12, theme='light'.
168
+ """
169
+ return self._invoke("get_report", {"report": report, "city": city, "compare": compare, "country": country, "date_from": date_from, "date_to": date_to, "days": days, "group_by": group_by, "limit": limit, "location_id": location_id, "max_cohorts": max_cohorts, "render": render, "theme": theme})
@@ -0,0 +1,100 @@
1
+ """
2
+ GENERATED by `python manage.py generate_python_sdk`. Do not edit.
3
+
4
+ Tools from mcp_server/tools/blog_tools.py.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, TypeVar
9
+
10
+ from ..types import UNSET, _Unset
11
+ from . import _ToolBase
12
+
13
+ R = TypeVar("R")
14
+
15
+
16
+ class BlogTools(_ToolBase[R]):
17
+ def create_article(self, blog_id: str, title: str, *, author_name: str | _Unset = UNSET, body_html: str | _Unset = UNSET, canonical_url: str | _Unset = UNSET, handle: str | _Unset = UNSET, image_alt: str | _Unset = UNSET, image_url: str | _Unset = UNSET, noindex: bool | _Unset = UNSET, published: bool | _Unset = UNSET, seo_description: str | _Unset = UNSET, seo_title: str | _Unset = UNSET, summary_html: str | _Unset = UNSET, tags: list[Any] | _Unset = UNSET) -> R:
18
+ """
19
+ Not idempotent - repeating it may act twice.
20
+
21
+ Write a blog article and optionally publish it.
22
+
23
+ Args:
24
+ blog_id: UUID or handle of the blog to post in (required).
25
+ title: Article title (required).
26
+ body_html: Full article body (HTML — sanitized on save).
27
+ summary_html: Optional excerpt/teaser HTML (auto-generated from the body
28
+ if left blank).
29
+ author_name: Display author name.
30
+ tags: List of tag strings.
31
+ handle: URL slug (`…/blog/<blog>/<handle>`). Auto-generated from the
32
+ title + de-duplicated within the blog if omitted.
33
+ image_url / image_alt: Featured / social-share image + alt text.
34
+ seo_title / seo_description: Meta title (≤ 70) + description (≤ 320).
35
+ canonical_url: Absolute canonical URL (leave blank normally).
36
+ noindex: True to hide from search engines.
37
+ published: True to publish now, False to save as a draft (default).
38
+
39
+ Returns:
40
+ The created article.
41
+
42
+ Omitted arguments are not sent; the store applies its own defaults: noindex=False, published=False.
43
+ """
44
+ return self._invoke("create_article", {"blog_id": blog_id, "title": title, "author_name": author_name, "body_html": body_html, "canonical_url": canonical_url, "handle": handle, "image_alt": image_alt, "image_url": image_url, "noindex": noindex, "published": published, "seo_description": seo_description, "seo_title": seo_title, "summary_html": summary_html, "tags": tags})
45
+
46
+ def create_blog(self, title: str, *, commentable: str | _Unset = UNSET, feedburner_url: str | _Unset = UNSET, handle: str | _Unset = UNSET, seo_description: str | _Unset = UNSET, seo_title: str | _Unset = UNSET, template_suffix: str | _Unset = UNSET) -> R:
47
+ """
48
+ Not idempotent - repeating it may act twice.
49
+
50
+ Create a new blog container.
51
+
52
+ Args:
53
+ title: Blog name (required), e.g. 'Plant Care Guides'.
54
+ handle: URL slug (`…/blog/<handle>`). Auto-generated from the
55
+ title and de-duplicated if omitted or already taken.
56
+ commentable: 'NO' (default) | 'MODERATE' | 'YES'.
57
+ seo_title: Meta title (≤ 70 chars).
58
+ seo_description: Meta description (≤ 320 chars).
59
+ feedburner_url: Optional RSS/FeedBurner URL.
60
+ template_suffix: Optional storefront template suffix.
61
+
62
+ Returns:
63
+ The created blog.
64
+
65
+ Omitted arguments are not sent; the store applies its own defaults: commentable='NO'.
66
+ """
67
+ return self._invoke("create_blog", {"title": title, "commentable": commentable, "feedburner_url": feedburner_url, "handle": handle, "seo_description": seo_description, "seo_title": seo_title, "template_suffix": template_suffix})
68
+
69
+ def update_article(self, article_id: str, *, author_name: str | _Unset = UNSET, blog_id: str | _Unset = UNSET, body_html: str | _Unset = UNSET, canonical_url: str | _Unset = UNSET, handle: str | _Unset = UNSET, image_alt: str | _Unset = UNSET, image_url: str | _Unset = UNSET, noindex: bool | _Unset = UNSET, published: bool | _Unset = UNSET, seo_description: str | _Unset = UNSET, seo_title: str | _Unset = UNSET, summary_html: str | _Unset = UNSET, tags: list[Any] | _Unset = UNSET, title: str | _Unset = UNSET) -> R:
70
+ """
71
+ Update an article. Any argument left as None is unchanged.
72
+
73
+ Args:
74
+ article_id: UUID of the article (must belong to your tenant).
75
+ blog_id: Move the article to a different blog (UUID or handle).
76
+ handle: New URL slug — slugified + de-duplicated within the blog.
77
+ published: True to publish, False to revert to a draft.
78
+ (other args mirror create_article; body_html/summary_html are sanitized.)
79
+
80
+ Returns:
81
+ The updated article.
82
+ """
83
+ return self._invoke("update_article", {"article_id": article_id, "author_name": author_name, "blog_id": blog_id, "body_html": body_html, "canonical_url": canonical_url, "handle": handle, "image_alt": image_alt, "image_url": image_url, "noindex": noindex, "published": published, "seo_description": seo_description, "seo_title": seo_title, "summary_html": summary_html, "tags": tags, "title": title})
84
+
85
+ def update_blog(self, blog_id: str, *, commentable: str | _Unset = UNSET, feedburner_url: str | _Unset = UNSET, handle: str | _Unset = UNSET, seo_description: str | _Unset = UNSET, seo_title: str | _Unset = UNSET, template_suffix: str | _Unset = UNSET, title: str | _Unset = UNSET) -> R:
86
+ """
87
+ Update a blog. Any argument left as None is unchanged.
88
+
89
+ Args:
90
+ blog_id: UUID or handle of the blog (must belong to your tenant).
91
+ handle: New URL slug — slugified + de-duplicated. NOTE: changing a
92
+ blog handle changes its public URL and does NOT auto-create
93
+ a redirect, so only rename handles for blogs with no traffic.
94
+ commentable: 'NO' | 'MODERATE' | 'YES'.
95
+ (other args mirror create_blog.)
96
+
97
+ Returns:
98
+ The updated blog.
99
+ """
100
+ return self._invoke("update_blog", {"blog_id": blog_id, "commentable": commentable, "feedburner_url": feedburner_url, "handle": handle, "seo_description": seo_description, "seo_title": seo_title, "template_suffix": template_suffix, "title": title})
@@ -0,0 +1,91 @@
1
+ """
2
+ GENERATED by `python manage.py generate_python_sdk`. Do not edit.
3
+
4
+ Tools from mcp_server/tools/branch_tools.py.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, TypeVar
9
+
10
+ from ..types import UNSET, _Unset
11
+ from . import _ToolBase
12
+
13
+ R = TypeVar("R")
14
+
15
+
16
+ class BranchTools(_ToolBase[R]):
17
+ def create_branch(self, name: str, *, address: dict[str, Any] | _Unset = UNSET, confirm: bool | _Unset = UNSET, fulfills_online_orders: bool | _Unset = UNSET, is_pos_branch: bool | _Unset = UNSET) -> R:
18
+ """
19
+ Requires confirm=True.
20
+ Not idempotent - repeating it may act twice.
21
+
22
+ Create a new branch/location (a shop or warehouse). is_pos_branch=True
23
+ makes it a physical sales branch that can run a POS counter; set
24
+ fulfills_online_orders=True if it should also ship web orders. Structural
25
+ change — requires confirm=True after the user approves.
26
+
27
+ Omitted arguments are not sent; the store applies its own defaults: confirm=False, fulfills_online_orders=False, is_pos_branch=True.
28
+ """
29
+ return self._invoke("create_branch", {"name": name, "address": address, "confirm": confirm, "fulfills_online_orders": fulfills_online_orders, "is_pos_branch": is_pos_branch})
30
+
31
+ def create_staff_member(self, email: str, *, branch_ids: list[Any] | _Unset = UNSET, confirm: bool | _Unset = UNSET, first_name: str | _Unset = UNSET, last_name: str | _Unset = UNSET, permissions: list[Any] | _Unset = UNSET, role_id: str | _Unset = UNSET) -> R:
32
+ """
33
+ Requires confirm=True.
34
+ Reaches outside the store (sends mail, calls a gateway, publishes).
35
+ Not idempotent - repeating it may act twice.
36
+
37
+ Invite a staff member (e.g. a branch manager): creates an inactive
38
+ account and emails them a set-password link (or promotes an existing
39
+ customer account in place). `branch_ids` scopes them to those branches
40
+ (empty = all branches); `permissions` grants capabilities such as
41
+ read_orders/write_orders/read_pos (see the store's roles for examples).
42
+ Grants access to the store — requires confirm=True after the user approves.
43
+
44
+ Omitted arguments are not sent; the store applies its own defaults: confirm=False.
45
+ """
46
+ return self._invoke("create_staff_member", {"email": email, "branch_ids": branch_ids, "confirm": confirm, "first_name": first_name, "last_name": last_name, "permissions": permissions, "role_id": role_id})
47
+
48
+ def list_staff(self) -> R:
49
+ """
50
+ Read-only.
51
+
52
+ List this store's staff members with their role, per-user capabilities and
53
+ assigned branches (empty branch list = all branches / head-office access).
54
+ Call this before set_staff_access to find the right user_id.
55
+ """
56
+ return self._invoke("list_staff", {})
57
+
58
+ def set_staff_access(self, user_id: str, *, branch_ids: list[Any] | _Unset = UNSET, confirm: bool | _Unset = UNSET, permissions: list[Any] | _Unset = UNSET, role_id: str | _Unset = UNSET) -> R:
59
+ """
60
+ DESTRUCTIVE - removes, overwrites or makes something irreversibly live.
61
+ Requires confirm=True.
62
+
63
+ Change a staff member's access: which branches they cover (empty list =
64
+ all branches), their per-user capabilities, and/or their role — e.g. make
65
+ someone the manager of a branch. Only the fields you pass change; the
66
+ others are left as they are. Changes what this person can do — requires
67
+ confirm=True after the user approves.
68
+
69
+ Omitted arguments are not sent; the store applies its own defaults: confirm=False.
70
+ """
71
+ return self._invoke("set_staff_access", {"user_id": user_id, "branch_ids": branch_ids, "confirm": confirm, "permissions": permissions, "role_id": role_id})
72
+
73
+ def transfer_stock(self, from_location_id: str, to_location_id: str, lines: list[Any], *, confirm: bool | _Unset = UNSET, note: str | _Unset = UNSET, reason: str | _Unset = UNSET, reference_document_uri: str | _Unset = UNSET) -> R:
74
+ """
75
+ Requires confirm=True.
76
+ Not idempotent - repeating it may act twice.
77
+
78
+ Move stock between branches. `lines` is a list of
79
+ {"variant_id": "<uuid>", "quantity": <int>} (max 100). All-or-nothing: any
80
+ under-stocked line rolls the whole transfer back. Physically relocates
81
+ inventory — requires confirm=True after the user approves the summary.
82
+ Use list_locations for branch ids and get_inventory_levels for stock.
83
+ `note` is free text kept on every line's ledger entry ("restocking Gulberg
84
+ before Eid"): the reason says what kind of movement this is, the note says
85
+ why this one happened. `reference_document_uri` is an optional http/https
86
+ link to the paperwork (a transfer note, a signed handover) kept on both
87
+ legs of every line.
88
+
89
+ Omitted arguments are not sent; the store applies its own defaults: confirm=False, reason='transfer'.
90
+ """
91
+ return self._invoke("transfer_stock", {"from_location_id": from_location_id, "to_location_id": to_location_id, "lines": lines, "confirm": confirm, "note": note, "reason": reason, "reference_document_uri": reference_document_uri})