Most Python developers can parse a CSV, write a decorator and pip install their way out of a problem.
Python experts know what happens when the operating system doesn't want you to do the thing: when a hotkey is reserved, when an audio device goes quiet, when a screen grab is slower than your frame rate, and when ctypes quietly cuts your pointers in half.
I found out which one I was while building ASNIPP: a screenshot tool, screen recorder, live-drawing overlay, colour picker and video editor for Windows. It is one Python file, about 7,600 lines, with no ads, no analytics and no network calls. Everything runs on your machine.
Every test below is a real bug or design decision from that file. The code is trimmed for reading, but the ideas are exactly what ships. Score yourself honestly. 👇
Test 1: Can you take a hotkey that Windows says is reserved?
I wanted Win+Shift+S to open ASNIPP instead of the Snipping Tool. The obvious tool is RegisterHotKey. It fails: that combo belongs to the shell.
The way in is a low-level keyboard hook (WH_KEYBOARD_LL) through ctypes. It sees the keystroke before anyone else, and if your callback returns 1, the key never reaches Windows.
def cb(nCode, wParam, lParam):
if nCode == 0 and wParam in (0x100, 0x101, 0x104, 0x105): # key down / up
kb = ctypes.cast(lParam, ctypes.POINTER(_KBDLLHOOKSTRUCT)).contents
if kb.vkCode in SNIP_HOOK_KEYS: # only S and R, nothing else
action, self._pending[kb.vkCode] = snip_hook_decision(
kb.vkCode, wParam in (0x100, 0x104), bool(kb.flags & 0x10),
pressed(0x5B, 0x5C), pressed(0x10), pressed(0x11), pressed(0x12),
self._pending.get(kb.vkCode, False))
if action == "trigger":
u.keybd_event(0xE8, 0, 0, 0) # inject an unassigned key...
u.keybd_event(0xE8, 0, 2, 0) # ...so releasing Win doesn't open Start
QTimer.singleShot(0, lambda: self.on_trigger("photo"))
return 1 # swallowed
if action == "swallow":
return 1
return u.CallNextHookEx(None, nCode, wParam, lParam)
self._proc = HOOKPROC(cb) # keep a reference or it gets garbage-collected
self.hook = u.SetWindowsHookExW(13, self._proc, k.GetModuleHandleW(None), 0)
Four details separate "it works once" from "it works":
-
Swallow the key-up too. If you eat the
Spress but let the release through, apps see a stray key-up. ASNIPP remembers it ate the press and eats exactly one release. -
Inject a dummy key (
0xE8). Press and releaseWinalone and Windows opens Start. A harmless unassigned keystroke in between cancels that. -
Ignore injected events (
flags & 0x10), or your ownkeybd_eventcall will trigger you again. -
The decision logic is a pure function with no
ctypesin it, so it can be tested without a keyboard:
def snip_hook_decision(vk, down, injected, win, shift, ctrl, alt, pending_up):
if injected or vk not in SNIP_HOOK_KEYS:
return "pass", pending_up
if down:
if win and shift and not ctrl and not alt:
return "trigger", True
return "pass", pending_up
if pending_up:
return "swallow", False
return "pass", pending_up
It only looks at S and R while Win+Shift are held. Nothing is logged or stored, and the source says so at the top of the class, because a keyboard hook should always be honest about what it reads.
Developer: pip install keyboard.
Expert: knows where the hook sits in the input chain, and writes the state machine as a pure function.
Test 2: Why is my recording's audio 40 seconds shorter than the video?
ASNIPP records system audio with WASAPI loopback. The first test recording looked fine, until I played a video with long silent parts: the sound drifted further and further ahead of the picture.
The cause: loopback delivers no data at all while nothing is playing. No callbacks, no zeros, nothing. If you just append whatever arrives, silence disappears from the file and everything after it slides earlier.
The fix is to treat the wall clock as the truth and pad the gaps yourself:
def push(self, data): # called from the audio thread
with self.lock:
if self.fill: # only for loopback, not the mic
now = rec.active_time() # seconds of *unpaused* recording
gap = int((now - n / self.rate) * self.rate) - self.frames
if gap > self.rate * 0.12: # ignore jitter under 120 ms
self._zeros(gap) # write real silence
self.f.write(pcm.tobytes())
self.frames += n
active_time() is perf_counter() minus the start time minus every second spent paused. So pausing the recording pauses the audio clock too.
Bonus trap: sounddevice has no WASAPI loopback. System audio needs PyAudioWPatch, with a "Stereo Mix" device as the fallback. ASNIPP tries both and tells the user which one is missing instead of silently recording nothing.
Developer: appends the bytes it receives.
Expert: asks "what does this API do when there is nothing to say?"
Test 3: What happens when grab() can't keep up with 30 FPS?
The recorder is a loop of mss.grab() → cv2.VideoWriter.write(). On a busy 4K screen a grab can take longer than 33 ms. If you write one frame per grab, a 10-second recording is stored as 6 seconds of video, and it plays back too fast.
The loop doesn't count frames. It counts time, and writes as many frames as the clock says are owed:
active += dt # unpaused seconds so far
img = sct.grab(self.monitor)
fr = np.ascontiguousarray(np.asarray(img)[:, :, :3]) # BGRA -> BGR
target = int(active * fps) + 1 # frames that SHOULD exist by now
n = max(1, min(target - written, fps)) # catch up, but never more than 1 s at once
for _ in range(n):
out.write(fr)
written += n
wait = written / fps - (active + (time.perf_counter() - last))
if wait > 0:
time.sleep(min(wait, 0.05)) # too fast? sleep. Too slow? duplicate.
A slow machine gets a few repeated frames. A fast machine gets a sleep. Either way the video is exactly as long as the real recording, which is what keeps the audio from Test 2 in sync.
Two small things make it production-grade: the min(..., fps) cap stops a long stall from dumping thousands of frames, and the audio clock starts from an on_ready callback fired right before the first frame, so both streams share the same zero.
Developer: time.sleep(1/30) in a loop.
Expert: knows sleep is a request, not a guarantee, and schedules against a clock.
Test 4: Why did my mic get quieter when I turned on system audio?
After recording, ASNIPP mixes the system track and the mic track into the MP4 with ffmpeg. Turn on both and the voice sounded half as loud.
amix divides each input by the number of inputs by default. Two tracks, so each is halved. The fix is normalize=0, but not every ffmpeg build knows that option, so the mixer tries variants in order and moves on when one fails:
variants = [
chains + [f"[a0][a1]amix=inputs=2:duration=longest:normalize=0,apad,atrim=0:{d}[m]"],
chains + [f"[a0][a1]amix=inputs=2:duration=longest,volume=2,apad,atrim=0:{d}[m]"], # older builds
]
for fc in variants:
ok, err = run_ffmpeg(args + ["-filter_complex", ";".join(fc), ...])
if ok:
break
Look at the tail too: apad,atrim=0:{d}. If the audio is a hair shorter than the video, ffmpeg's -shortest would cut the video. Padding the audio and then trimming to the exact video length means a short track can never shorten the video.
And if ffmpeg is missing entirely? ASNIPP mixes the tracks in pure NumPy and saves a .wav next to the video, with a note saying what to install. It degrades, it doesn't crash.
Developer: ffmpeg -i a -i b out.mp4.
Expert: reads what each filter assumes, and keeps a plan B.
Test 5: Why does GetWindowLongPtrW return garbage in Python?
Live drawing mode puts a transparent overlay over your whole screen. Sometimes you want to click through it to the app underneath. That is the WS_EX_TRANSPARENT window style, set through ctypes:
u = ctypes.windll.user32
get_l, set_l = u.GetWindowLongPtrW, u.SetWindowLongPtrW
get_l.restype = ctypes.c_ssize_t # <- the whole point
get_l.argtypes = [ctypes.c_void_p, ctypes.c_int]
set_l.restype = ctypes.c_ssize_t
set_l.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_ssize_t]
hwnd = int(widget.winId())
st = get_l(hwnd, -20) # GWL_EXSTYLE
st = (st | 0x20 | 0x80000) if on else (st & ~0x20) # TRANSPARENT | LAYERED
set_l(hwnd, -20, st)
ctypes assumes every foreign function returns a 32-bit int and takes 32-bit arguments. On 64-bit Windows, handles and pointer-sized values are 64 bits, so without restype and argtypes you get truncated values, sign errors and crashes that only appear on some machines. Declare every signature, every time.
The function also falls back to Qt's own WA_TransparentForMouseEvents if the Win32 route fails, and a 32-bit Python gets GetWindowLongW instead. Same idea as Test 4: the ideal path first, and an honest fallback after.
Developer: copies the snippet from Stack Overflow.
Expert: writes down the C signature before calling the C function.
Test 6: Does "delete" actually mean delete?
ASNIPP's library has a delete button. os.remove() is permanent, and nobody forgives a tool that permanently deletes their screenshot after one misclick. So deleting sends the file to the Recycle Bin, using SHFileOperationW and no third-party package:
class SHFILEOPSTRUCTW(ctypes.Structure):
_pack_ = 1 if ctypes.sizeof(ctypes.c_void_p) == 4 else 8 # 32 vs 64-bit layout
_fields_ = [("hwnd", wt.HWND), ("wFunc", wt.UINT), ("pFrom", wt.LPCWSTR),
("pTo", wt.LPCWSTR), ("fFlags", ctypes.c_ushort),
("fAnyOperationsAborted", wt.BOOL), ("hNameMappings", ctypes.c_void_p),
("lpszProgressTitle", wt.LPCWSTR)]
op = SHFILEOPSTRUCTW()
op.wFunc = 3 # FO_DELETE
op.pFrom = os.path.abspath(path) + "\0" # must end in TWO nulls (Python adds one)
op.fFlags = 0x40 | 0x10 | 0x4 | 0x400 # ALLOWUNDO | NOCONFIRM | SILENT | NOERRORUI
res = ctypes.windll.shell32.SHFileOperationW(ctypes.byref(op))
return res == 0 and not op.fAnyOperationsAborted and not os.path.exists(path)
The last line matters most. The function returns True only if the file is really gone. Not "the call returned 0". Not "no exception". The API said yes and the filesystem agrees.
If it can't reach the Recycle Bin (some network drives), the UI can say so rather than claim a delete that didn't happen.
Developer: trusts the return code.
Expert: verifies the world changed.
Test 7: Is your eyedropper accurate to the pixel on a scaled display?
ASNIPP has a colour picker with a magnifier and a pixel ruler. The first version was off by one pixel on my laptop, and by several on my friend's 150% display.
Two decisions fixed it:
1. Freeze the screen first. The picker doesn't read live pixels. It hides ASNIPP's own island, waits 160 ms for the compositor, grabs the screen once, and works on that frozen image. Menus, tooltips and hover states stay exactly as they were when you pressed the key.
def _grab_prepare(self, mode):
self.island.hide()
QTimer.singleShot(160, lambda: self._grab(mode)) # let the window really disappear
def _grab(self, mode):
pix = screen.grabWindow(0)
pix.setDevicePixelRatio(1.0) # work in true device pixels
2. Never assume widget size equals image size. Convert with a ratio, clamp, and put the point back at the centre of its pixel:
def _sx(self): return self.img.width() / max(self.width(), 1)
def _to_img(self, pt): # widget -> image pixel
return QPoint(min(max(int(pt.x() * self._sx()), 0), self.img.width() - 1),
min(max(int(pt.y() * self._sy()), 0), self.img.height() - 1))
def _to_view(self, ip): # image pixel -> widget
return QPointF((ip.x() + 0.5) / self._sx(), (ip.y() + 0.5) / self._sy())
That + 0.5 is the trick. A pixel is a square, not a point. Draw the crosshair on its corner and everything looks half a pixel off. The ruler also snaps to 45° steps with one line of atan2:
ang = round(math.atan2(dy, dx) / (math.pi / 4)) * (math.pi / 4)
Developer: int(event.x()) and hope.
Expert: knows a pixel has a centre, and that screens have scale factors.
Test 8: Can your app leave the PC exactly how it found it?
To own PrintScreen, ASNIPP has to turn off a Windows setting (PrintScreenKeyForSnippingEnabled) in the registry. That is the user's setting, not mine. So the takeover is a reversible transaction:
cur = read_prtscn_setting()
if cur != 0:
if self.settings.get("prev_prtscn") == -1: # remember it ONCE
self.settings.set("prev_prtscn", cur)
write_prtscn_setting(0)
...
# turning ASNIPP's takeover off again:
prev = self.settings.get("prev_prtscn")
if prev in (0, 1):
write_prtscn_setting(prev) # put it back
Around that sit a handful of unglamorous habits that make software feel trustworthy:
-
Settings are written atomically. Write
settings.json.tmp, thenos.replace()over the real file. A crash mid-write can't leave half a file. -
Settings are type-checked on load. A value is only accepted if
isinstance(raw[k], type(default)). A hand-edited"autostart": "yes"can't break startup. - Apply first, explain second. On first run the takeover is applied before the dialog appears, so closing the box can't undo it.
-
Never show a dialog during a silent login start (
--background). -
One instance only. A named mutex, and
GetLastError() == 183(ERROR_ALREADY_EXISTS) means "someone is already holding the hotkeys, so exit quietly". -
"Start with Windows" is opt-in, and the command it writes handles Nuitka builds, PyInstaller builds and plain
pythonw.exe.
Developer: ships features.
Expert: ships an undo button for every side effect.
Bonus: OCR with zero pip packages
ASNIPP can copy text out of any screenshot. No Tesseract, no model download. Windows already ships an OCR engine (Windows.Media.Ocr), and Python can drive it through PowerShell:
with open(ps1, "w", encoding="utf-8-sig") as f: # BOM so PowerShell reads Unicode correctly
f.write(script)
subprocess.run(["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ps1],
capture_output=True, timeout=120, creationflags=0x08000000) # no console flash
The utf-8-sig is the whole lesson: without the BOM, Windows PowerShell 5 reads the script as the legacy code page and non-English text turns to mush. And 0x08000000 (CREATE_NO_WINDOW) stops a black console from flashing on screen every time you press the button.
Also from the file: ffmpeg's atempo only accepts 0.5x to 2x, so a 4x speed-up has to be chained (atempo=2.0,atempo=2.0). A tiny while loop in atempo_chain() does it.
Try the code yourself
All of this lives in ASNIPP, built by Akhouri Systems: a pure-Python Windows app with a "Dynamic Island" style capture bar. It has no ads, no analytics and no network calls. It does exactly what's on the tin, and the hook in Test 1 only ever looks at the keys it needs.
| What you get | Details |
|---|---|
| 📸 Photo capture |
Win+Shift+S, Ctrl+Shift+S or PrintScreen. Region, window or full screen, copied to clipboard and saved |
| 🎥 Screen recorder |
Win+Shift+R, with system audio + mic, pause and a recording border that never appears in the video |
| ✏️ Live drawing |
Ctrl+Alt+D. Pen, shapes, laser pointer and auto-fade, over any app, and it can be recorded |
| 🎯 Colour picker + ruler |
Ctrl+Alt+P. Magnifier, HEX/RGB copy, pixel distances and angles |
| 🎞️ Video editor | Trim, split, join, speed, reverse, rotate, looks, GIF export |
| 🔤 OCR + pins | Copy text from any screenshot, pin an image on top of every window |
If you're learning how Python behaves outside a notebook, run it, press Win+Shift+S, and then ask yourself what is happening between your keypress and the screen. That is the fastest way I know to level up.
Try ASNIPP_v1:https://github.com/Akhouri-Systems/ASNIPP/releases/download/v1.0.0/ASNIPP_v1.zip
not just try it, break it too.
I want feedbacks because feedbacks would make ASNIPP_v2 better.
Your score
- 0-2 tests known: You're a Python developer. Great start. Now write something that has to talk to the OS.
- 3-5: Solid. You've shipped something real.
- 6-8: You're a Python expert. Come argue with me in the comments.
Which test did you fail first? Mine was Test 2: a recording that looked perfect until the first long silence, then slowly drifted out of sync. I lost two evenings to it. Tell me yours below 👇
Top comments (50)
@akhourianmolkumar & @technogamerz I came to the latest post...
yeah okay I'm online from now.
I will be online during breaks 😑
okay..
👍
whenever you get a break say something here.
ok 👍
okay 👌
bro akhouri systems crossed 1.5k downloads....
I had already seen it. But congratulations! 🎉
How many downloads to release APIC v2?
2000
Me janti hu Akhouri system ko tab se jab uske 300 download the.🙋🏻♀️ sorry 120
I'm 13. Built a software company. 2 months. 120 downloads. The honest story.
yeah oldest family member of Akhouri Systems....
before you I think only one mustafa erbay came in acalcu post and then you?
or first you and then he and then xulingfeng in 3rd
Hmm, I don't remember 🤔. Maybe @merbayerp knows.
yeah I think he commented first among my best bros now like he gave me feedbacks for acalcu v3
Ohhh, now I remember! Remember I once told you I’d get Akhouri system promoted? Around that time, I also told Mustafa that there was a teenager who needed some motivation, and I think I asked him to motivate you. I don't remember the exact details, though. But I guess I've known Mustafa for quite a long time!
lol you said him to motivate you, now he is the most experienced person in akhouri systems team 😂
but whatt thanks didi, means because of you I got him, & a IITian in akhouri systems side means you too
Akhouri Systems is now 5months old.... time flies fast....
from may 2026(79) to october 4 2026(1519)
@effessdev bro would get all my history of these 5months from this chat 😆
Ugh I joined DEV.to only 5 months ago or something
hmm I joined in june.
Oh then it's not bad. I joined in may.
oh, and you are with akhouri systems for 1months almost....
in 1 month you gained the title of CTO @ Akhouri Systems 💀
and best bro too 😂
Oh it has been 1 month?!
yup
Wow!
Bro since UnitBuilds' game is not 1m but 11m loc what are your thoughts?
Me
what you think IIT would call me too 😂? for akhouri systems
What??? So I joined first?!
yeah probably IIT will call you too...!
means? if you consider job then first I offered CTO post to Mustafa ERBAY but he firstly denied to be officially but later on he slightly accepted by some small diplomatic signals to yeah he is Co-CTO because the head CTO or main CTO is occupied by mr. @effessdev
hmm or maybe in future I Call them for Akhouri Systems sponsoring there IIT 😂
I mean I joined DEV.to first 🤣 It's crazy that Mustafa ERBAY is co-CTO bro...
why crazy 😆
hehehehehe, aura for a reason
🥳 Glad that I became first!
yeah otherwise you might be co-CTO & he main CTO 😂
Me in 8 class
my employees: 💀
Bruh I don't know how to respond... 🤦♂️🤦♂️
me waiting for your reply bruh 😆
🤦♂️
To be honest, I’m practically a pre-beginner Python coder. Around 2019, I was very keen on becoming a Python developer to complement my existing skills as a React developer. However, the company I was working for at the time didn't look favorably upon me exploring solutions that deviated from their standard tech stack. Consequently, the only thing I managed to achieve was connecting JS and Python via WebSockets, which allowed me to utilize an OpenAI translation function from within a JS application.
Nowadays, though, it doesn't really matter which programming language I use or what I’m building. I’ve started developing a 3D engine, and I was surprised to find that—alongside TS and Hexaw—it actually includes some Python code as well.
Thanks for sharing thiss, Peter bro! And “pre-beginner” undersells it. bridging JS and Python over WebSockets to call a translation function is real integration work, and it’s the kind of thing that teaches you how systems talk to each other.
I agree with your point about language not mattering much. mostt of the tests in this post are really about the OS, not Python: a hotkey Windows reserves, an audio device that goes silent, a pointer that gets truncated. you’d hit the same walls in C#, Rust or JS. Python just made it easy to reach them quicklyyy.
A 3D engine with TS, Hexaw and a Bit of Python sounds really interestiing. What does the Python part do in it...? tooling, asset processing, something else?
thanks for commenting and sharing this again... ;)
Good question, just for loading blender file to AI.
github.com/Pengeszikra/3Draft
... under heavy development.
.... under heavy development 😆☠️
thanks for sharing this.
Great write-up! I especially liked the audio synchronization issue and the reminder that a successful API call doesn’t always mean the expected result actually happened. These are the kinds of lessons that come from real debugging experience. Thanks for sharing both the challenges and the solutions!
Thanks broo. really glad those two landed the audio one surprised me most, because nothing crashes.... the recording just looks fine until the first long silence, and then the sound slowly slides out of sync.. Bugs thatt fail quietly are the hardest to catch.
the “verify the world changed” idea came from the same Place. a function returning success told me nothing until i checked that the file was really gone.
Have you hit a bug like that bro??, where the API said yes but reality said no? also bro now I've created a series: Developer or Expert I like the series concept of xulingfeng so from him I took inspiration to create a series.
Absolutely, bro! I’ve encountered similar situations in infrastructure and automation, where an API reports success but the actual system state tells a different story. That’s why I’ve learned to trust verification more than return codes. Silent failures are especially tricky because everything looks fine until something unexpected happens. 😄
I also like the Developer or Expert series concept. Looking forward to the next one!
yeah next post soon.... ;)
bro see this:
Hands down Test 1 (Low-level keyboard hooks and message pump thread affinity).
When building automated agents that interact with Windows desktop environments via ctypes and native Win32, the hidden trap is WH_KEYBOARD_LL running on a secondary thread that doesn't maintain a dedicated, unblocked GetMessageW / DispatchMessageW pump.
If any synchronous I/O or LLM parsing blocks that thread for more than LowLevelHooksTimeout (typically 200–1000ms in Windows registry), the OS silently unhooks your callback without throwing an exception! You think the hook is still alive, but Windows just quietly stopped delivering WM_KEYDOWN.
Moving the hook callback to an isolated worker thread with a dedicated Win32 message loop while buffering events into an asynchronous queue is the only way we achieved 24/7 rock-solid stability in production.
Also, massive kudos for using SHFileOperationW with FO_DELETE + FOF_ALLOWUNDO instead of raw os.remove(). That single detail separates developers from engineers who build software for humans.
The obsession with wrapping remote APIs into multi-layered agent abstractions is creating massive hidden latency and failure cascades in production.
If you profile real-world workloads, bare-metal local inference (via direct C++ / llama.cpp or vLLM bindings) consistently beats fragile cloud wrappers on both predictability and cost. Tooling should eliminate abstraction penalties, not compound them.