Unable to update post through API (Python)


I’m trying to update my post directly with the Ghost API, but that does not work as expected.
Here is my code, at the end I got a http status code 200 but the content of the post is not updated.

def put_update_post(id_post=None, title=None, old_post=None, updated_post=None, oldTitle=None, newTitle="MyTest", body=None, bodyFormat='html', excerpt = None, tags=None, authors=None, status='draft', featured=False, featureImage=None):
    print("id_post : {}".format(id_post))
    date_ = str((datetime.datetime.now(timezone.utc)).strftime('%Y-%m-%dT%H:%M:%S.000Z'))
    if id_post == None and title != None:
        id_post = search_post_id_from_title(title)
    elif id_post == None and title == None:
        return -1
        content = {"posts": [{"title": newTitle}]}
        content["posts"][0]['html'] = json.dumps("<p> HELLO </p>")
        content["posts"][0]['authors'] = [{ "id": "1" }]
        content["posts"][0]['status'] = "published"
        content["posts"][0]['featured'] = False
        content["posts"][0]['updated_at'] =  str(date_) 
        content["posts"][0]['tags'] = [{ "name": "Blue Team", "description": "blue-team" }]
        url=config.ghost_admin_url + "posts/" + str(id_post) + "/"
        response = requests.put(url=url, headers=headers, json=content)
        if str(response.status_code)[0] == '2':
            return response.json()
            return -1

The result of the code in the console :

id_post : 6493f7xxxxxx
{'Access-Control-Allow-Methods': 'PUT', 'Content-Type': 'application/json;charset=utf-8', 'Authorization': 'Ghost xxxx'}
{'posts': [{'title': 'TEST TEST', 'html': '"<p> HELLO </p>"', 'authors': [{'id': '1'}], 'status': 'published', 'featured': False, 'updated_at': '2023-06-22T08:10:40.000Z', 'tags': [{'name': 'Blue Team', 'description': 'blue-team'}]}]}

Thank you in advance.

If you’re doing a PUT, you have to pass an updated_at that matches what’s already on the post, not the current time.

Hello, thank you but it is not the issue.

I just fixed it by adding

content['mobiledoc'] = json.dumps({ 'version': '0.3.1', 'markups': [], 'atoms': [], 'cards': [['html', {'cardName': 'html', 'html': body}]], 'sections': [[10, 0]]});

Just before:

content["posts"][0]['html'] = json.dumps("<p> HELLO </p>")

Best regards

Oh good, glad you figured it out! :) Embedding HTML in a card is definitely one option. You can also pass HTML without putting it into a card, if it’s simple enough HTML that the HTML parser can understand it. Or at least you could a couple versions ago - with the new lexical editor, I’m not 100% sure if it still works the way I’ve done it.

1 Like