This is an automated email from the ASF dual-hosted git repository.

henry3260 pushed a commit to branch airflow-ctl/v0-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/airflow-ctl/v0-1-test by this 
push:
     new 19e2ec1a22f [airflow-ctl/v0-1-test] Add asset state store commands to 
airflowctl (#70771) (#72742)
19e2ec1a22f is described below

commit 19e2ec1a22fd8aebd01ec427299f4efb41c0751f
Author: Henry Chen <[email protected]>
AuthorDate: Wed Sep 9 03:08:10 2026 +0800

    [airflow-ctl/v0-1-test] Add asset state store commands to airflowctl 
(#70771) (#72742)
    
    Manual backport. This branch's core API spec (3.2.1) does not include the
    asset state-store endpoints, so the AssetStateStore* datamodels were added
    to generated.py by hand instead of via datamodel-codegen, and the assets
    help SVG was regenerated from this branch. The field_bool_default_datamodels
    context from main and the unrelated queued-event delete tests were left out
    because the tasks clear backport is not on this branch.
    
    (cherry picked from commit fb512efe2ac7cee7ecd861e392ad310e7844d990)
    
    Co-authored-by: Justin Pakzad 
<[email protected]>
---
 .../airflowctl_tests/test_airflowctl_commands.py   |   6 +
 airflow-ctl/docs/images/command_hashes.txt         |   2 +-
 airflow-ctl/docs/images/output_assets.svg          | 166 ++++++++++++---------
 .../src/airflowctl/api/datamodels/generated.py     |  57 +++++++
 airflow-ctl/src/airflowctl/api/operations.py       |  36 +++++
 airflow-ctl/src/airflowctl/ctl/cli_config.py       |  13 +-
 airflow-ctl/src/airflowctl/ctl/help_texts.yaml     |   5 +
 .../tests/airflow_ctl/api/test_operations.py       |  75 +++++++++-
 8 files changed, 290 insertions(+), 70 deletions(-)

diff --git 
a/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py 
b/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
index 67c241b440f..5d8500b6ed8 100644
--- a/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
+++ b/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
@@ -56,6 +56,12 @@ TEST_COMMANDS = [
     "assets list",
     "assets get 1",
     "assets create-event --asset-id=1",
+    "assets set-state-store 1 test_key test_value",
+    "assets get-state-store 1 test_key",
+    "assets list-state-store 1",
+    "assets delete-state-store 1 test_key",
+    "assets set-state-store 1 clear_key value",
+    "assets clear-state-store 1",
     # Backfill commands
     "backfill list example_bash_operator",
     # Config commands
diff --git a/airflow-ctl/docs/images/command_hashes.txt 
b/airflow-ctl/docs/images/command_hashes.txt
index 15f0640ac06..765b0bd02e1 100644
--- a/airflow-ctl/docs/images/command_hashes.txt
+++ b/airflow-ctl/docs/images/command_hashes.txt
@@ -1,5 +1,5 @@
 main:27a22c00dcf32e7a1a4f06672dc8e3c8
-assets:70619a2d92bda80930cde2aefcd8e1cd
+assets:4ec546634ac98b220969450db85b98d1
 auth:d79e9c7d00c432bdbcbc2a86e2e32053
 backfill:74c8737b0a62a86ed3605fa9e6165874
 config:a3d936cb15fe3b547bf6c82cf93d923f
diff --git a/airflow-ctl/docs/images/output_assets.svg 
b/airflow-ctl/docs/images/output_assets.svg
index b76118dc52a..3a7486c1869 100644
--- a/airflow-ctl/docs/images/output_assets.svg
+++ b/airflow-ctl/docs/images/output_assets.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 933 733.1999999999999" 
xmlns="http://www.w3.org/2000/svg";>
+<svg class="rich-terminal" viewBox="0 0 933 928.4" 
xmlns="http://www.w3.org/2000/svg";>
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -19,150 +19,182 @@
         font-weight: 700;
     }
 
-    .terminal-3582101150-matrix {
+    .terminal-223707050-matrix {
         font-family: Fira Code, monospace;
         font-size: 20px;
         line-height: 24.4px;
         font-variant-east-asian: full-width;
     }
 
-    .terminal-3582101150-title {
+    .terminal-223707050-title {
         font-size: 18px;
         font-weight: bold;
         font-family: arial;
     }
 
-    .terminal-3582101150-r1 { fill: #ff8700 }
-.terminal-3582101150-r2 { fill: #c5c8c6 }
-.terminal-3582101150-r3 { fill: #808080 }
-.terminal-3582101150-r4 { fill: #68a0b3 }
+    .terminal-223707050-r1 { fill: #ff8700 }
+.terminal-223707050-r2 { fill: #c5c8c6 }
+.terminal-223707050-r3 { fill: #808080 }
+.terminal-223707050-r4 { fill: #68a0b3 }
     </style>
 
     <defs>
-    <clipPath id="terminal-3582101150-clip-terminal">
-      <rect x="0" y="0" width="914.0" height="682.1999999999999" />
+    <clipPath id="terminal-223707050-clip-terminal">
+      <rect x="0" y="0" width="914.0" height="877.4" />
     </clipPath>
-    <clipPath id="terminal-3582101150-line-0">
+    <clipPath id="terminal-223707050-line-0">
     <rect x="0" y="1.5" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-1">
+<clipPath id="terminal-223707050-line-1">
     <rect x="0" y="25.9" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-2">
+<clipPath id="terminal-223707050-line-2">
     <rect x="0" y="50.3" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-3">
+<clipPath id="terminal-223707050-line-3">
     <rect x="0" y="74.7" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-4">
+<clipPath id="terminal-223707050-line-4">
     <rect x="0" y="99.1" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-5">
+<clipPath id="terminal-223707050-line-5">
     <rect x="0" y="123.5" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-6">
+<clipPath id="terminal-223707050-line-6">
     <rect x="0" y="147.9" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-7">
+<clipPath id="terminal-223707050-line-7">
     <rect x="0" y="172.3" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-8">
+<clipPath id="terminal-223707050-line-8">
     <rect x="0" y="196.7" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-9">
+<clipPath id="terminal-223707050-line-9">
     <rect x="0" y="221.1" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-10">
+<clipPath id="terminal-223707050-line-10">
     <rect x="0" y="245.5" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-11">
+<clipPath id="terminal-223707050-line-11">
     <rect x="0" y="269.9" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-12">
+<clipPath id="terminal-223707050-line-12">
     <rect x="0" y="294.3" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-13">
+<clipPath id="terminal-223707050-line-13">
     <rect x="0" y="318.7" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-14">
+<clipPath id="terminal-223707050-line-14">
     <rect x="0" y="343.1" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-15">
+<clipPath id="terminal-223707050-line-15">
     <rect x="0" y="367.5" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-16">
+<clipPath id="terminal-223707050-line-16">
     <rect x="0" y="391.9" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-17">
+<clipPath id="terminal-223707050-line-17">
     <rect x="0" y="416.3" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-18">
+<clipPath id="terminal-223707050-line-18">
     <rect x="0" y="440.7" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-19">
+<clipPath id="terminal-223707050-line-19">
     <rect x="0" y="465.1" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-20">
+<clipPath id="terminal-223707050-line-20">
     <rect x="0" y="489.5" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-21">
+<clipPath id="terminal-223707050-line-21">
     <rect x="0" y="513.9" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-22">
+<clipPath id="terminal-223707050-line-22">
     <rect x="0" y="538.3" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-23">
+<clipPath id="terminal-223707050-line-23">
     <rect x="0" y="562.7" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-24">
+<clipPath id="terminal-223707050-line-24">
     <rect x="0" y="587.1" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-25">
+<clipPath id="terminal-223707050-line-25">
     <rect x="0" y="611.5" width="915" height="24.65"/>
             </clipPath>
-<clipPath id="terminal-3582101150-line-26">
+<clipPath id="terminal-223707050-line-26">
     <rect x="0" y="635.9" width="915" height="24.65"/>
             </clipPath>
+<clipPath id="terminal-223707050-line-27">
+    <rect x="0" y="660.3" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-28">
+    <rect x="0" y="684.7" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-29">
+    <rect x="0" y="709.1" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-30">
+    <rect x="0" y="733.5" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-31">
+    <rect x="0" y="757.9" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-32">
+    <rect x="0" y="782.3" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-33">
+    <rect x="0" y="806.7" width="915" height="24.65"/>
+            </clipPath>
+<clipPath id="terminal-223707050-line-34">
+    <rect x="0" y="831.1" width="915" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="931" height="731.2" rx="8"/>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" 
x="1" y="1" width="931" height="926.4" rx="8"/>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
             <circle cx="44" cy="0" r="7" fill="#28c840"/>
             </g>
         
-    <g transform="translate(9, 41)" 
clip-path="url(#terminal-3582101150-clip-terminal)">
+    <g transform="translate(9, 41)" 
clip-path="url(#terminal-223707050-clip-terminal)">
     
-    <g class="terminal-3582101150-matrix">
-    <text class="terminal-3582101150-r1" x="0" y="20" textLength="73.2" 
clip-path="url(#terminal-3582101150-line-0)">Usage:</text><text 
class="terminal-3582101150-r3" x="85.4" y="20" textLength="207.4" 
clip-path="url(#terminal-3582101150-line-0)">airflowctl&#160;assets</text><text 
class="terminal-3582101150-r2" x="292.8" y="20" textLength="24.4" 
clip-path="url(#terminal-3582101150-line-0)">&#160;[</text><text 
class="terminal-3582101150-r4" x="317.2" y="20" textLength="24.4" clip-path="ur 
[...]
-</text><text class="terminal-3582101150-r2" x="915" y="44.4" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-1)">
-</text><text class="terminal-3582101150-r2" x="0" y="68.8" textLength="305" 
clip-path="url(#terminal-3582101150-line-2)">Perform&#160;Assets&#160;operations</text><text
 class="terminal-3582101150-r2" x="915" y="68.8" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-2)">
-</text><text class="terminal-3582101150-r2" x="915" y="93.2" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-3)">
-</text><text class="terminal-3582101150-r1" x="0" y="117.6" textLength="256.2" 
clip-path="url(#terminal-3582101150-line-4)">Positional&#160;Arguments:</text><text
 class="terminal-3582101150-r2" x="915" y="117.6" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-4)">
-</text><text class="terminal-3582101150-r4" x="24.4" y="142" textLength="85.4" 
clip-path="url(#terminal-3582101150-line-5)">COMMAND</text><text 
class="terminal-3582101150-r2" x="915" y="142" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-5)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="166.4" 
textLength="146.4" 
clip-path="url(#terminal-3582101150-line-6)">create-event</text><text 
class="terminal-3582101150-r2" x="292.8" y="166.4" textLength="402.6" 
clip-path="url(#terminal-3582101150-line-6)">Create&#160;an&#160;event&#160;for&#160;a&#160;given&#160;asset</text><text
 class="terminal-3582101150-r2" x="915" y="166.4" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-6)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="190.8" 
textLength="292.8" 
clip-path="url(#terminal-3582101150-line-7)">delete-dag-queued-events</text><text
 class="terminal-3582101150-r2" x="915" y="190.8" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-7)">
-</text><text class="terminal-3582101150-r2" x="292.8" y="215.2" 
textLength="561.2" 
clip-path="url(#terminal-3582101150-line-8)">Delete&#160;all&#160;queued&#160;asset&#160;events&#160;for&#160;a&#160;given&#160;Dag</text><text
 class="terminal-3582101150-r2" x="915" y="215.2" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-8)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="239.6" 
textLength="231.8" 
clip-path="url(#terminal-3582101150-line-9)">delete-queued-event</text><text 
class="terminal-3582101150-r2" x="915" y="239.6" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-9)">
-</text><text class="terminal-3582101150-r2" x="292.8" y="264" 
textLength="597.8" 
clip-path="url(#terminal-3582101150-line-10)">Delete&#160;a&#160;specific&#160;queued&#160;asset&#160;event&#160;for&#160;a&#160;given&#160;</text><text
 class="terminal-3582101150-r2" x="915" y="264" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-10)">
-</text><text class="terminal-3582101150-r2" x="0" y="288.4" textLength="158.6" 
clip-path="url(#terminal-3582101150-line-11)">Dag&#160;and&#160;asset</text><text
 class="terminal-3582101150-r2" x="915" y="288.4" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-11)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="312.8" 
textLength="244" 
clip-path="url(#terminal-3582101150-line-12)">delete-queued-events</text><text 
class="terminal-3582101150-r2" x="915" y="312.8" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-12)">
-</text><text class="terminal-3582101150-r2" x="292.8" y="337.2" 
textLength="512.4" 
clip-path="url(#terminal-3582101150-line-13)">Delete&#160;all&#160;queued&#160;events&#160;for&#160;a&#160;given&#160;asset</text><text
 class="terminal-3582101150-r2" x="915" y="337.2" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-13)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="361.6" 
textLength="36.6" clip-path="url(#terminal-3582101150-line-14)">get</text><text 
class="terminal-3582101150-r2" x="292.8" y="361.6" textLength="329.4" 
clip-path="url(#terminal-3582101150-line-14)">Retrieve&#160;an&#160;asset&#160;by&#160;its&#160;ID</text><text
 class="terminal-3582101150-r2" x="915" y="361.6" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-14)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="386" 
textLength="146.4" 
clip-path="url(#terminal-3582101150-line-15)">get-by-alias</text><text 
class="terminal-3582101150-r2" x="292.8" y="386" textLength="366" 
clip-path="url(#terminal-3582101150-line-15)">Retrieve&#160;an&#160;asset&#160;by&#160;its&#160;alias</text><text
 class="terminal-3582101150-r2" x="915" y="386" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-15)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="410.4" 
textLength="244" 
clip-path="url(#terminal-3582101150-line-16)">get-dag-queued-event</text><text 
class="terminal-3582101150-r2" x="915" y="410.4" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-16)">
-</text><text class="terminal-3582101150-r2" x="292.8" y="434.8" 
textLength="622.2" 
clip-path="url(#terminal-3582101150-line-17)">Retrieve&#160;a&#160;specific&#160;queued&#160;asset&#160;event&#160;for&#160;a&#160;given&#160;</text><text
 class="terminal-3582101150-r2" x="915" y="434.8" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-17)">
-</text><text class="terminal-3582101150-r2" x="0" y="459.2" textLength="158.6" 
clip-path="url(#terminal-3582101150-line-18)">Dag&#160;and&#160;asset</text><text
 class="terminal-3582101150-r2" x="915" y="459.2" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-18)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="483.6" 
textLength="256.2" 
clip-path="url(#terminal-3582101150-line-19)">get-dag-queued-events</text><text 
class="terminal-3582101150-r2" x="915" y="483.6" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-19)">
-</text><text class="terminal-3582101150-r2" x="292.8" y="508" textLength="488" 
clip-path="url(#terminal-3582101150-line-20)">List&#160;queued&#160;asset&#160;events&#160;for&#160;a&#160;given&#160;Dag</text><text
 class="terminal-3582101150-r2" x="915" y="508" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-20)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="532.4" 
textLength="207.4" 
clip-path="url(#terminal-3582101150-line-21)">get-queued-events</text><text 
class="terminal-3582101150-r2" x="292.8" y="532.4" textLength="439.2" 
clip-path="url(#terminal-3582101150-line-21)">List&#160;queued&#160;events&#160;for&#160;a&#160;given&#160;asset</text><text
 class="terminal-3582101150-r2" x="915" y="532.4" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-21)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="556.8" 
textLength="48.8" 
clip-path="url(#terminal-3582101150-line-22)">list</text><text 
class="terminal-3582101150-r2" x="292.8" y="556.8" textLength="183" 
clip-path="url(#terminal-3582101150-line-22)">List&#160;all&#160;assets</text><text
 class="terminal-3582101150-r2" x="915" y="556.8" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-22)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="581.2" 
textLength="158.6" 
clip-path="url(#terminal-3582101150-line-23)">list-by-alias</text><text 
class="terminal-3582101150-r2" x="292.8" y="581.2" textLength="268.4" 
clip-path="url(#terminal-3582101150-line-23)">List&#160;all&#160;asset&#160;aliases</text><text
 class="terminal-3582101150-r2" x="915" y="581.2" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-23)">
-</text><text class="terminal-3582101150-r4" x="48.8" y="605.6" 
textLength="134.2" 
clip-path="url(#terminal-3582101150-line-24)">materialize</text><text 
class="terminal-3582101150-r2" x="292.8" y="605.6" textLength="549" 
clip-path="url(#terminal-3582101150-line-24)">Trigger&#160;materialization&#160;of&#160;an&#160;asset&#160;by&#160;its&#160;ID</text><text
 class="terminal-3582101150-r2" x="915" y="605.6" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-24)">
-</text><text class="terminal-3582101150-r2" x="915" y="630" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-25)">
-</text><text class="terminal-3582101150-r1" x="0" y="654.4" textLength="97.6" 
clip-path="url(#terminal-3582101150-line-26)">Options:</text><text 
class="terminal-3582101150-r2" x="915" y="654.4" textLength="12.2" 
clip-path="url(#terminal-3582101150-line-26)">
-</text><text class="terminal-3582101150-r4" x="24.4" y="678.8" 
textLength="24.4" clip-path="url(#terminal-3582101150-line-27)">-h</text><text 
class="terminal-3582101150-r2" x="48.8" y="678.8" textLength="24.4" 
clip-path="url(#terminal-3582101150-line-27)">,&#160;</text><text 
class="terminal-3582101150-r4" x="73.2" y="678.8" textLength="73.2" 
clip-path="url(#terminal-3582101150-line-27)">--help</text><text 
class="terminal-3582101150-r2" x="292.8" y="678.8" textLength="378.2" 
clip-path="ur [...]
+    <g class="terminal-223707050-matrix">
+    <text class="terminal-223707050-r1" x="0" y="20" textLength="73.2" 
clip-path="url(#terminal-223707050-line-0)">Usage:</text><text 
class="terminal-223707050-r3" x="85.4" y="20" textLength="207.4" 
clip-path="url(#terminal-223707050-line-0)">airflowctl&#160;assets</text><text 
class="terminal-223707050-r2" x="292.8" y="20" textLength="24.4" 
clip-path="url(#terminal-223707050-line-0)">&#160;[</text><text 
class="terminal-223707050-r4" x="317.2" y="20" textLength="24.4" 
clip-path="url(#term [...]
+</text><text class="terminal-223707050-r2" x="915" y="44.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-1)">
+</text><text class="terminal-223707050-r2" x="0" y="68.8" textLength="305" 
clip-path="url(#terminal-223707050-line-2)">Perform&#160;Assets&#160;operations</text><text
 class="terminal-223707050-r2" x="915" y="68.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-2)">
+</text><text class="terminal-223707050-r2" x="915" y="93.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-3)">
+</text><text class="terminal-223707050-r1" x="0" y="117.6" textLength="256.2" 
clip-path="url(#terminal-223707050-line-4)">Positional&#160;Arguments:</text><text
 class="terminal-223707050-r2" x="915" y="117.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-4)">
+</text><text class="terminal-223707050-r4" x="24.4" y="142" textLength="85.4" 
clip-path="url(#terminal-223707050-line-5)">COMMAND</text><text 
class="terminal-223707050-r2" x="915" y="142" textLength="12.2" 
clip-path="url(#terminal-223707050-line-5)">
+</text><text class="terminal-223707050-r4" x="48.8" y="166.4" 
textLength="207.4" 
clip-path="url(#terminal-223707050-line-6)">clear-state-store</text><text 
class="terminal-223707050-r2" x="292.8" y="166.4" textLength="610" 
clip-path="url(#terminal-223707050-line-6)">Delete&#160;all&#160;state&#160;store&#160;keys&#160;for&#160;an&#160;asset&#160;by&#160;its&#160;ID</text><text
 class="terminal-223707050-r2" x="915" y="166.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-6)">
+</text><text class="terminal-223707050-r4" x="48.8" y="190.8" 
textLength="146.4" 
clip-path="url(#terminal-223707050-line-7)">create-event</text><text 
class="terminal-223707050-r2" x="292.8" y="190.8" textLength="402.6" 
clip-path="url(#terminal-223707050-line-7)">Create&#160;an&#160;event&#160;for&#160;a&#160;given&#160;asset</text><text
 class="terminal-223707050-r2" x="915" y="190.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-7)">
+</text><text class="terminal-223707050-r4" x="48.8" y="215.2" 
textLength="292.8" 
clip-path="url(#terminal-223707050-line-8)">delete-dag-queued-events</text><text
 class="terminal-223707050-r2" x="915" y="215.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-8)">
+</text><text class="terminal-223707050-r2" x="292.8" y="239.6" 
textLength="561.2" 
clip-path="url(#terminal-223707050-line-9)">Delete&#160;all&#160;queued&#160;asset&#160;events&#160;for&#160;a&#160;given&#160;Dag</text><text
 class="terminal-223707050-r2" x="915" y="239.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-9)">
+</text><text class="terminal-223707050-r4" x="48.8" y="264" textLength="231.8" 
clip-path="url(#terminal-223707050-line-10)">delete-queued-event</text><text 
class="terminal-223707050-r2" x="915" y="264" textLength="12.2" 
clip-path="url(#terminal-223707050-line-10)">
+</text><text class="terminal-223707050-r2" x="292.8" y="288.4" 
textLength="597.8" 
clip-path="url(#terminal-223707050-line-11)">Delete&#160;a&#160;specific&#160;queued&#160;asset&#160;event&#160;for&#160;a&#160;given&#160;</text><text
 class="terminal-223707050-r2" x="915" y="288.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-11)">
+</text><text class="terminal-223707050-r2" x="0" y="312.8" textLength="158.6" 
clip-path="url(#terminal-223707050-line-12)">Dag&#160;and&#160;asset</text><text
 class="terminal-223707050-r2" x="915" y="312.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-12)">
+</text><text class="terminal-223707050-r4" x="48.8" y="337.2" textLength="244" 
clip-path="url(#terminal-223707050-line-13)">delete-queued-events</text><text 
class="terminal-223707050-r2" x="915" y="337.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-13)">
+</text><text class="terminal-223707050-r2" x="292.8" y="361.6" 
textLength="512.4" 
clip-path="url(#terminal-223707050-line-14)">Delete&#160;all&#160;queued&#160;events&#160;for&#160;a&#160;given&#160;asset</text><text
 class="terminal-223707050-r2" x="915" y="361.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-14)">
+</text><text class="terminal-223707050-r4" x="48.8" y="386" textLength="219.6" 
clip-path="url(#terminal-223707050-line-15)">delete-state-store</text><text 
class="terminal-223707050-r2" x="292.8" y="386" textLength="622.2" 
clip-path="url(#terminal-223707050-line-15)">Delete&#160;a&#160;single&#160;asset&#160;state&#160;store&#160;key&#160;by&#160;its&#160;ID&#160;and</text><text
 class="terminal-223707050-r2" x="915" y="386" textLength="12.2" 
clip-path="url(#terminal-223707050-line-15)">
+</text><text class="terminal-223707050-r2" x="0" y="410.4" textLength="36.6" 
clip-path="url(#terminal-223707050-line-16)">key</text><text 
class="terminal-223707050-r2" x="915" y="410.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-16)">
+</text><text class="terminal-223707050-r4" x="48.8" y="434.8" 
textLength="36.6" clip-path="url(#terminal-223707050-line-17)">get</text><text 
class="terminal-223707050-r2" x="292.8" y="434.8" textLength="329.4" 
clip-path="url(#terminal-223707050-line-17)">Retrieve&#160;an&#160;asset&#160;by&#160;its&#160;ID</text><text
 class="terminal-223707050-r2" x="915" y="434.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-17)">
+</text><text class="terminal-223707050-r4" x="48.8" y="459.2" 
textLength="146.4" 
clip-path="url(#terminal-223707050-line-18)">get-by-alias</text><text 
class="terminal-223707050-r2" x="292.8" y="459.2" textLength="366" 
clip-path="url(#terminal-223707050-line-18)">Retrieve&#160;an&#160;asset&#160;by&#160;its&#160;alias</text><text
 class="terminal-223707050-r2" x="915" y="459.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-18)">
+</text><text class="terminal-223707050-r4" x="48.8" y="483.6" textLength="244" 
clip-path="url(#terminal-223707050-line-19)">get-dag-queued-event</text><text 
class="terminal-223707050-r2" x="915" y="483.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-19)">
+</text><text class="terminal-223707050-r2" x="292.8" y="508" 
textLength="622.2" 
clip-path="url(#terminal-223707050-line-20)">Retrieve&#160;a&#160;specific&#160;queued&#160;asset&#160;event&#160;for&#160;a&#160;given&#160;</text><text
 class="terminal-223707050-r2" x="915" y="508" textLength="12.2" 
clip-path="url(#terminal-223707050-line-20)">
+</text><text class="terminal-223707050-r2" x="0" y="532.4" textLength="158.6" 
clip-path="url(#terminal-223707050-line-21)">Dag&#160;and&#160;asset</text><text
 class="terminal-223707050-r2" x="915" y="532.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-21)">
+</text><text class="terminal-223707050-r4" x="48.8" y="556.8" 
textLength="256.2" 
clip-path="url(#terminal-223707050-line-22)">get-dag-queued-events</text><text 
class="terminal-223707050-r2" x="915" y="556.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-22)">
+</text><text class="terminal-223707050-r2" x="292.8" y="581.2" 
textLength="488" 
clip-path="url(#terminal-223707050-line-23)">List&#160;queued&#160;asset&#160;events&#160;for&#160;a&#160;given&#160;Dag</text><text
 class="terminal-223707050-r2" x="915" y="581.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-23)">
+</text><text class="terminal-223707050-r4" x="48.8" y="605.6" 
textLength="207.4" 
clip-path="url(#terminal-223707050-line-24)">get-queued-events</text><text 
class="terminal-223707050-r2" x="292.8" y="605.6" textLength="439.2" 
clip-path="url(#terminal-223707050-line-24)">List&#160;queued&#160;events&#160;for&#160;a&#160;given&#160;asset</text><text
 class="terminal-223707050-r2" x="915" y="605.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-24)">
+</text><text class="terminal-223707050-r4" x="48.8" y="630" textLength="183" 
clip-path="url(#terminal-223707050-line-25)">get-state-store</text><text 
class="terminal-223707050-r2" x="292.8" y="630" textLength="622.2" 
clip-path="url(#terminal-223707050-line-25)">Retrieve&#160;a&#160;single&#160;asset&#160;state&#160;store&#160;entry&#160;by&#160;its&#160;ID</text><text
 class="terminal-223707050-r2" x="915" y="630" textLength="12.2" 
clip-path="url(#terminal-223707050-line-25)">
+</text><text class="terminal-223707050-r2" x="0" y="654.4" textLength="85.4" 
clip-path="url(#terminal-223707050-line-26)">and&#160;key</text><text 
class="terminal-223707050-r2" x="915" y="654.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-26)">
+</text><text class="terminal-223707050-r4" x="48.8" y="678.8" 
textLength="48.8" clip-path="url(#terminal-223707050-line-27)">list</text><text 
class="terminal-223707050-r2" x="292.8" y="678.8" textLength="183" 
clip-path="url(#terminal-223707050-line-27)">List&#160;all&#160;assets</text><text
 class="terminal-223707050-r2" x="915" y="678.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-27)">
+</text><text class="terminal-223707050-r4" x="48.8" y="703.2" 
textLength="158.6" 
clip-path="url(#terminal-223707050-line-28)">list-by-alias</text><text 
class="terminal-223707050-r2" x="292.8" y="703.2" textLength="268.4" 
clip-path="url(#terminal-223707050-line-28)">List&#160;all&#160;asset&#160;aliases</text><text
 class="terminal-223707050-r2" x="915" y="703.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-28)">
+</text><text class="terminal-223707050-r4" x="48.8" y="727.6" 
textLength="195.2" 
clip-path="url(#terminal-223707050-line-29)">list-state-store</text><text 
class="terminal-223707050-r2" x="292.8" y="727.6" textLength="500.2" 
clip-path="url(#terminal-223707050-line-29)">List&#160;all&#160;state&#160;store&#160;entries&#160;for&#160;an&#160;asset</text><text
 class="terminal-223707050-r2" x="915" y="727.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-29)">
+</text><text class="terminal-223707050-r4" x="48.8" y="752" textLength="134.2" 
clip-path="url(#terminal-223707050-line-30)">materialize</text><text 
class="terminal-223707050-r2" x="292.8" y="752" textLength="549" 
clip-path="url(#terminal-223707050-line-30)">Trigger&#160;materialization&#160;of&#160;an&#160;asset&#160;by&#160;its&#160;ID</text><text
 class="terminal-223707050-r2" x="915" y="752" textLength="12.2" 
clip-path="url(#terminal-223707050-line-30)">
+</text><text class="terminal-223707050-r4" x="48.8" y="776.4" textLength="183" 
clip-path="url(#terminal-223707050-line-31)">set-state-store</text><text 
class="terminal-223707050-r2" x="292.8" y="776.4" textLength="610" 
clip-path="url(#terminal-223707050-line-31)">Set&#160;an&#160;asset&#160;state&#160;store&#160;value.&#160;Parsed&#160;as&#160;JSON&#160;if&#160;</text><text
 class="terminal-223707050-r2" x="915" y="776.4" textLength="12.2" 
clip-path="url(#terminal-223707050-line-31)">
+</text><text class="terminal-223707050-r2" x="0" y="800.8" textLength="427" 
clip-path="url(#terminal-223707050-line-32)">valid,&#160;otherwise&#160;stored&#160;as&#160;a&#160;string</text><text
 class="terminal-223707050-r2" x="915" y="800.8" textLength="12.2" 
clip-path="url(#terminal-223707050-line-32)">
+</text><text class="terminal-223707050-r2" x="915" y="825.2" textLength="12.2" 
clip-path="url(#terminal-223707050-line-33)">
+</text><text class="terminal-223707050-r1" x="0" y="849.6" textLength="97.6" 
clip-path="url(#terminal-223707050-line-34)">Options:</text><text 
class="terminal-223707050-r2" x="915" y="849.6" textLength="12.2" 
clip-path="url(#terminal-223707050-line-34)">
+</text><text class="terminal-223707050-r4" x="24.4" y="874" textLength="24.4" 
clip-path="url(#terminal-223707050-line-35)">-h</text><text 
class="terminal-223707050-r2" x="48.8" y="874" textLength="24.4" 
clip-path="url(#terminal-223707050-line-35)">,&#160;</text><text 
class="terminal-223707050-r4" x="73.2" y="874" textLength="73.2" 
clip-path="url(#terminal-223707050-line-35)">--help</text><text 
class="terminal-223707050-r2" x="292.8" y="874" textLength="378.2" 
clip-path="url(#terminal-223 [...]
 </text>
     </g>
     </g>
diff --git a/airflow-ctl/src/airflowctl/api/datamodels/generated.py 
b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
index 43719cbb096..df61627c77b 100644
--- a/airflow-ctl/src/airflowctl/api/datamodels/generated.py
+++ b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
@@ -67,6 +67,20 @@ class BaseInfoResponse(BaseModel):
     status: Annotated[str | None, Field(title="Status")] = None
 
 
+class AssetStateStoreWriterKind(str, Enum):
+    """
+    Identifies what kind of writer last updated an asset state store entry.
+
+    ``TASK`` — written by a task via the execution API.
+    ``WATCHER`` — written by a ``BaseEventTrigger`` (no task instance).
+    ``API`` — written directly through the Core API (e.g. manual admin write).
+    """
+
+    TASK = "task"
+    WATCHER = "watcher"
+    API = "api"
+
+
 class BulkActionNotOnExistence(str, Enum):
     """
     Bulk Action to be taken if the entity does not exist.
@@ -1118,6 +1132,40 @@ class AssetResponse(BaseModel):
     last_asset_event: LastAssetEventResponse | None = None
 
 
+class AssetStateStoreBody(BaseModel):
+    """
+    Request body for setting an asset state store value.
+    """
+
+    model_config = ConfigDict(
+        extra="forbid",
+    )
+    value: JsonValue
+
+
+class AssetStateStoreLastUpdatedBy(BaseModel):
+    """
+    Writer info for the last write to an asset state store entry.
+    """
+
+    kind: AssetStateStoreWriterKind
+    dag_id: Annotated[str | None, Field(title="Dag Id")] = None
+    run_id: Annotated[str | None, Field(title="Run Id")] = None
+    task_id: Annotated[str | None, Field(title="Task Id")] = None
+    map_index: Annotated[int | None, Field(title="Map Index")] = None
+
+
+class AssetStateStoreResponse(BaseModel):
+    """
+    A single asset state store key/value pair with metadata.
+    """
+
+    key: Annotated[str, Field(title="Key")]
+    value: JsonValue
+    updated_at: Annotated[datetime, Field(title="Updated At")]
+    last_updated_by: AssetStateStoreLastUpdatedBy | None = None
+
+
 class BackfillPostBody(BaseModel):
     """
     Object used for create backfill request.
@@ -1864,6 +1912,15 @@ class AssetEventCollectionResponse(BaseModel):
     total_entries: Annotated[int, Field(title="Total Entries")]
 
 
+class AssetStateStoreCollectionResponse(BaseModel):
+    """
+    All asset state store entries for an asset.
+    """
+
+    asset_state_store: Annotated[list[AssetStateStoreResponse], 
Field(title="Asset State Store")]
+    total_entries: Annotated[int, Field(title="Total Entries")]
+
+
 class BackfillCollectionResponse(BaseModel):
     """
     Backfill Collection serializer for responses.
diff --git a/airflow-ctl/src/airflowctl/api/operations.py 
b/airflow-ctl/src/airflowctl/api/operations.py
index 22b203c3c5c..8a1e1f3b263 100644
--- a/airflow-ctl/src/airflowctl/api/operations.py
+++ b/airflow-ctl/src/airflowctl/api/operations.py
@@ -32,6 +32,9 @@ from airflowctl.api.datamodels.generated import (
     AssetCollectionResponse,
     AssetEventResponse,
     AssetResponse,
+    AssetStateStoreBody,
+    AssetStateStoreCollectionResponse,
+    AssetStateStoreResponse,
     BackfillCollectionResponse,
     BackfillPostBody,
     BackfillResponse,
@@ -354,6 +357,39 @@ class AssetsOperations(BaseOperations):
         except ServerResponseError as e:
             raise e
 
+    def list_state_store(self, asset_id: str) -> 
AssetStateStoreCollectionResponse | ServerResponseError:
+        """List all state store entries for an asset."""
+        return super().execute_list(
+            path=f"assets/{asset_id}/state-store", 
data_model=AssetStateStoreCollectionResponse
+        )
+
+    def get_state_store(self, asset_id: str, key: str) -> 
AssetStateStoreResponse | ServerResponseError:
+        """Get a single asset state store entry."""
+        self.response = self.client.get(f"assets/{asset_id}/state-store/{key}")
+        return 
AssetStateStoreResponse.model_validate_json(self.response.content)
+
+    def set_state_store(self, asset_id: str, key: str, value: str) -> str | 
ServerResponseError:
+        """Set an asset state store value. Creates or overwrites the key."""
+        try:
+            parsed_value = json.loads(value)
+        except (ValueError, TypeError):
+            parsed_value = value
+        self.client.put(
+            f"assets/{asset_id}/state-store/{key}",
+            
json=AssetStateStoreBody(value=parsed_value).model_dump(mode="json"),
+        )
+        return key
+
+    def delete_state_store(self, asset_id: str, key: str) -> str | 
ServerResponseError:
+        """Delete a single asset state store key."""
+        self.client.delete(f"assets/{asset_id}/state-store/{key}")
+        return key
+
+    def clear_state_store(self, asset_id: str) -> str | ServerResponseError:
+        """Delete all state store keys for an asset."""
+        self.client.delete(f"assets/{asset_id}/state-store")
+        return asset_id
+
 
 class BackfillOperations(BaseOperations):
     """Backfill operations."""
diff --git a/airflow-ctl/src/airflowctl/ctl/cli_config.py 
b/airflow-ctl/src/airflowctl/ctl/cli_config.py
index 44db6367ecf..8306393a556 100755
--- a/airflow-ctl/src/airflowctl/ctl/cli_config.py
+++ b/airflow-ctl/src/airflowctl/ctl/cli_config.py
@@ -415,7 +415,18 @@ class CommandFactory:
         # Exclude parameters that are not needed for CLI from datamodels
         self.excluded_parameters = ["schema_"]
         # This list is used to determine if the command/operation needs to 
output data
-        self.output_command_list = ["list", "get", "create", "delete", 
"update", "trigger", "add", "edit"]
+        self.output_command_list = [
+            "list",
+            "get",
+            "create",
+            "delete",
+            "update",
+            "trigger",
+            "add",
+            "edit",
+            "set",
+            "clear",
+        ]
         self.exclude_operation_names = ["LoginOperations", 
"VersionOperations", "BaseOperations"]
         self.exclude_method_names = [
             "error",
diff --git a/airflow-ctl/src/airflowctl/ctl/help_texts.yaml 
b/airflow-ctl/src/airflowctl/ctl/help_texts.yaml
index fbc31194894..69cc8a47a00 100644
--- a/airflow-ctl/src/airflowctl/ctl/help_texts.yaml
+++ b/airflow-ctl/src/airflowctl/ctl/help_texts.yaml
@@ -28,6 +28,11 @@ assets:
   delete-queued-events: "Delete all queued events for a given asset"
   delete-dag-queued-events: "Delete all queued asset events for a given Dag"
   delete-queued-event: "Delete a specific queued asset event for a given Dag 
and asset"
+  list-state-store: "List all state store entries for an asset"
+  get-state-store: "Retrieve a single asset state store entry by its ID and 
key"
+  set-state-store: "Set an asset state store value. Parsed as JSON if valid, 
otherwise stored as a string"
+  delete-state-store: "Delete a single asset state store key by its ID and key"
+  clear-state-store: "Delete all state store keys for an asset by its ID"
 
 backfill:
   create: "Create a backfill job for a given Dag ID and date range"
diff --git a/airflow-ctl/tests/airflow_ctl/api/test_operations.py 
b/airflow-ctl/tests/airflow_ctl/api/test_operations.py
index bcef9acd74a..c2a4e40c15f 100644
--- a/airflow-ctl/tests/airflow_ctl/api/test_operations.py
+++ b/airflow-ctl/tests/airflow_ctl/api/test_operations.py
@@ -36,6 +36,8 @@ from airflowctl.api.datamodels.generated import (
     AssetCollectionResponse,
     AssetEventResponse,
     AssetResponse,
+    AssetStateStoreCollectionResponse,
+    AssetStateStoreResponse,
     BackfillCollectionResponse,
     BackfillPostBody,
     BackfillResponse,
@@ -313,7 +315,11 @@ class TestAssetsOperations:
         queued_events=[asset_queued_event_response],
         total_entries=1,
     )
-
+    asset_state_store_response = AssetStateStoreResponse(
+        key="my_key",
+        value={"my_val": 0},  # type: ignore[arg-type]
+        updated_at=datetime.datetime(2025, 1, 1, 0, 0, 0),
+    )
     dag_run_response = DAGRunResponse(
         dag_display_name=dag_id,
         dag_run_id=dag_id,
@@ -468,6 +474,73 @@ class TestAssetsOperations:
         response = client.assets.get_dag_queued_event(dag_id=self.dag_id, 
asset_id=self.asset_id)
         assert response == self.asset_queued_event_response
 
+    def test_list_state_store(self):
+        collection_response = AssetStateStoreCollectionResponse(
+            asset_state_store=[self.asset_state_store_response],
+            total_entries=1,
+        )
+
+        def handle_request(request: httpx.Request) -> httpx.Response:
+            assert request.url.path == 
f"/api/v2/assets/{self.asset_id}/state-store"
+            return httpx.Response(200, 
json=json.loads(collection_response.model_dump_json()))
+
+        client = make_api_client(transport=httpx.MockTransport(handle_request))
+        response = client.assets.list_state_store(self.asset_id)
+        assert response == collection_response
+
+    def test_get_state_store(self):
+        key = self.asset_state_store_response.key
+
+        def handle_request(request: httpx.Request) -> httpx.Response:
+            assert request.url.path == 
f"/api/v2/assets/{self.asset_id}/state-store/{key}"
+            return httpx.Response(200, 
json=json.loads(self.asset_state_store_response.model_dump_json()))
+
+        client = make_api_client(transport=httpx.MockTransport(handle_request))
+        response = client.assets.get_state_store(self.asset_id, key)
+        assert response == self.asset_state_store_response
+
+    @pytest.mark.parametrize(
+        ("value", "expected"),
+        [
+            ('{"index": 0}', {"index": 0}),
+            ("hello", "hello"),
+        ],
+    )
+    def test_set_state_store(self, value, expected):
+        key = self.asset_state_store_response.key
+
+        def handle_request(request: httpx.Request) -> httpx.Response:
+            assert request.method == "PUT"
+            assert request.url.path == 
f"/api/v2/assets/{self.asset_id}/state-store/{key}"
+            assert json.loads(request.content) == {"value": expected}
+            return httpx.Response(204)
+
+        client = make_api_client(transport=httpx.MockTransport(handle_request))
+        response = client.assets.set_state_store(self.asset_id, key, value)
+        assert response == key
+
+    def test_delete_state_store(self):
+        key = self.asset_state_store_response.key
+
+        def handle_request(request: httpx.Request) -> httpx.Response:
+            assert request.method == "DELETE"
+            assert request.url.path == 
f"/api/v2/assets/{self.asset_id}/state-store/{key}"
+            return httpx.Response(204)
+
+        client = make_api_client(transport=httpx.MockTransport(handle_request))
+        response = client.assets.delete_state_store(self.asset_id, key)
+        assert response == key
+
+    def test_clear_state_store(self):
+        def handle_request(request: httpx.Request) -> httpx.Response:
+            assert request.method == "DELETE"
+            assert request.url.path == 
f"/api/v2/assets/{self.asset_id}/state-store"
+            return httpx.Response(204)
+
+        client = make_api_client(transport=httpx.MockTransport(handle_request))
+        response = client.assets.clear_state_store(self.asset_id)
+        assert response == self.asset_id
+
 
 class TestBackfillOperations:
     backfill_id: NonNegativeInt = 1

Reply via email to