GitHub user dosubot[bot] added a comment to the discussion: update dataset via api from python - CSRF token
<!-- Greeting --> Hi @mestachs! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the superset team. <!-- Answer --> Superset enforces CSRF protection on modifying API endpoints (like PUT to /api/v1/dataset/{id}) even when using Bearer JWT authentication, due to the @protect() decorator on those routes. This means you must include a CSRF token in your requests, not just the Authorization header with your JWT token [cite](https://github.com/apache/superset/discussions/35855). To update a dataset via the API from Python, use requests.Session() to manage cookies, and follow this workflow: 1. Log in to get your access token. 2. Add the Authorization header to your session. 3. Fetch the CSRF token from /api/v1/security/csrf_token/ (with the Authorization header set). 4. Add the CSRF token to your session headers as X-CSRFToken. 5. Make your PUT request with the same session. Example: ```python import requests session = requests.Session() # 1. Login login_resp = session.post( "https://your-superset/api/v1/security/login", json={"username": "your_user", "password": "your_pass", "provider": "db"} ) access_token = login_resp.json()["access_token"] session.headers.update({"Authorization": f"Bearer {access_token}"}) # 2. Get CSRF token csrf_resp = session.get("https://your-superset/api/v1/security/csrf_token/") csrf_token = csrf_resp.json()["result"] session.headers.update({"X-CSRFToken": csrf_token}) # 3. Update dataset resp = session.put( f"https://your-superset/api/v1/dataset/{dataset_id}", json=dataset_payload ) print(resp.json()) ``` Do not manually set the Cookie header; let requests.Session() handle it [cite](https://github.com/apache/superset/discussions/35855). If you get a 422 error from the CSRF endpoint about "Subject must be a string", make sure the 'sub' claim in your JWT is a string, not an integer [cite](https://github.com/apache/superset/issues/31675). There is no supported way to disable CSRF for API endpoints using JWT Bearer tokens in Superset. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=other)</sup> [](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github) [](https://cursor.com/link/prompt?text=Superset%20enforces%20CSRF%20protection%20on%20modifying%20API%20endpoints%20%28like%20PUT%20to%20/api/v1/dataset/%7Bid%7D%29%20even%20when%20using%20Bearer%20JWT%20authentication%2C%20due%20to%20the%20%40protect%28%29%20decorator%20on%20those%20routes.%20This%20means%20you%20must%20include%20a%20CSRF%20token%20in%20your%20requests%2C%20not%20just%20the%20Authorization%20header%20with%20your%20JWT%20token%C2%A0%5Bcite%5D%28https%3A//github.com/apache/superset/discussions/35855%29.%0A%0ATo%20update%20a%20dataset%20via%20the%20API%20from%20Python%2C%20use%20requests.Session%28%29%20to%20manage%20cookies%2C%20and%20follow%20this%20workflow%3A%0A%0A1.%20Log%20in%20to%20get%20your%20access%20token.%0A2.%20Add%20the%20Authorization%20header%20to%20your%20se ssion.%0A3.%20Fetch%20the%20CSRF%20token%20from%20/api/v1/security/csrf_token/%20%28with%20the%20Authorization%20header%20set%29.%0A4.%20Add%20the%20CSRF%20token%20to%20your%20session%20headers%20as%20X-CSRFToken.%0A5.%20Make%20your%20PUT%20request%20with%20the%20same%20session.%0A%0AExample%3A%0A%0A%60%60%60python%0Aimport%20requests%0A%0Asession%20%3D%20requests.Session%28%29%0A%0A%23%201.%20Login%0Alogin_resp%20%3D%20session.post%28%0A%20%20%20%20%22https%3A//your-superset/api/v1/security/login%22%2C%0A%20%20%20%20json%3D%7B%22username%22%3A%20%22your_user%22%2C%20%22password%22%3A%20%22your_pass%22%2C%20%22provider%22%3A%20%22db%22%7D%0A%29%0Aaccess_token%20%3D%20login_resp.json%28%29%5B%22access_token%22%5D%0Asession.headers.update%28%7B%22Authorization%22%3A%20f%22Bearer%20%7Baccess_token%7D%22%7D%29%0A%0A%23%202.%20Get%20CSRF%20token%0Acsrf_resp%20%3D%20session.get%28%22https%3A//your-superset/api/v1/security/csrf_token/%22%29%0Acsrf_token%20%3D%20csrf_resp.json%28%29%5B%22re sult%22%5D%0Asession.headers.update%28%7B%22X-CSRFToken%22%3A%20csrf_token%7D%29%0A%0A%23%203.%20Update%20dataset%0Aresp%20%3D%20session.put%28%0A%20%20%20%20f%22https%3A//your-superset/api/v1/dataset/%7Bdataset_id%7D%22%2C%0A%20%20%20%20json%3Ddataset_payload%0A%29%0Aprint%28resp.json%28%29%29%0A%60%60%60%0A%0ADo%20not%20manually%20set%20the%20Cookie%20header%3B%20let%20requests.Session%28%29%20handle%20it%C2%A0%5Bcite%5D%28https%3A//github.com/apache/superset/discussions/35855%29.%0A%0AIf%20you%20get%20a%20422%20error%20from%20the%20CSRF%20endpoint%20about%20%22Subject%20must%20be%20a%20string%22%2C%20make%20sure%20the%20%27sub%27%20claim%20in%20your%20JWT%20is%20a%20string%2C%20not%20an%20integer%C2%A0%5Bcite%5D%28https%3A//github.com/apache/superset/issues/31675%29.%0A%0AThere%20is%20no%20supported%20way%20to%20disable%20CSRF%20for%20API%20endpoints%20using%20JWT%20Bearer%20tokens%20in%20Superset.) [](https://go.dosu.dev/discord-bot) [](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/36409) GitHub link: https://github.com/apache/superset/discussions/36409#discussioncomment-15148909 ---- This is an automatically sent email for [email protected]. To unsubscribe, please send an email to: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
