How to toggle Xray in viewport with Python?

From the interface you get this command (which return a failed context error when run from the console):

bpy.ops.view3d.toggle_xray()


On the manual there is unfortunately no tooltip that would give any help (search page for xray with ctrl+F): https://docs.blender.org/api/current/bpy.ops.view3d.html

Has anyone successfully toggled xrays with python?

Often the UI code gives clues

Turn on developer extras in user preferences and can right click and view source of most UI elements.

Do this over toggle xray button and It takes us to the draw code, in text editor, of the operator button in 3d view.

In space_view3d.py

    row.operator(
"view3d.toggle_xray",
text="",
icon='XRAY',
depress=getattr(
"show_xray_wireframe" if shading.type == 'WIREFRAME' else
"show_xray"
),


Trecking up we see shading is a pointer property of the SpaceView3d This is context.space_data in the 3d view, but not in text editor or console. A reason for the failed context error.

-- remnder: post like to codemanx's override context answer, or easier still See Merlin's answer --

We could simply find the area and space and other required members and pass as an override dictionary to the operator, however we may be able to simply toggle a property of the space.. much easier.. off to the python console to investigate

get all the 3d view areas in the context screen

>>> views3d = [a for a in C.screen.areas if a.type == 'VIEW_3D']


iterate over them and see what the values are using code above as clue. The space from an area is area.spaces.active

>>> for a in views3d:
...
'SOLID'
True
True


Hmm ok let's see

>>> shading.show_xray = False
>>>


and bingo, toggles shading. I'll leave you to decide on how to handle show_xray_wireframe based on shading.type

Although @batFINGER has provided a more complete answer, I was part way through this and thought I'd share an alternate way using a context override:

# toggle xray for 3d view in all windows
import bpy

for window in bpy.context.window_manager.windows:
screen = window.screen

for area in screen.areas:
if area.type == 'VIEW_3D':
override = {'window': window, 'screen': screen, 'area': area}
bpy.ops.view3d.toggle_xray(override)
break