Use the INSERT ... ON CONFLICT
with the WHERE
condition as you showed it.
Then check how many rows were affected, and if there was none, throw an error. You can do that either in client code or in a database function.
With psycopg2, you can get the number of rows modified from the rowcount
property of the cursor, as shown in this answer.