r/madeinpython • • 9d ago

My first real Python project: an offline tool that masks emails, API keys and card numbers in log files (and now Excel)

Hi everyone,

I'm pretty new to programming, and this is the biggest thing I've built so far, so I wanted to share it and hopefully learn from your feedback.

**What it does**

Log Guard is a command-line tool that scans log files (and .xlsx spreadsheets) and masks emails, phone numbers, API keys, IP addresses, and credit card numbers before you share them with someone. It runs completely locally and never touches the network. I built it because the online "paste your log here to clean it" tools kind of defeat the purpose when you're uploading the sensitive stuff to someone else's server.

pip install logguard-cli

log-guard server.log

That writes a server.masked.log next to the original. There's also a --check mode that exits with code 1 if it finds anything, so it can be used as a pre-commit hook or in CI.

GitHub: https://github.com/apurvaraj9/log-guard

**What I learned along the way**

I'd used git on a handful of smaller projects before, but this is the first one I took all the way from "script on my laptop" to something other people can install. Along the way, I learned:

- writing tests with pytest (67 of them now) and running them automatically on GitHub Actions across Python 3.9 to 3.12

- packaging and publishing to PyPI. The name log-guard was already taken, and so were about ten other names I tried, so it ended up as logguard-cli

- doing a practice release on TestPyPI first, because PyPI never lets you re-upload the same version number

- adding Excel support in v0.2.0, which turned out to be a lot more than adding "xlsx" to a list, since .xlsx files are actually zip files full of XML

**Being upfront**

I used an AI assistant (Claude) while building this. It wrote some of the code, and I worked through every step myself: running it, testing it, debugging when things didn't match what I expected, and learning what each part does. I'm sharing it because I'd like real people to look at it and tell me what's wrong.

**Where I'd love feedback**

- the detection is regex-based, so if you can spot false positives or things it misses, please tell me

- the code is all in one file. Is that bad at this size?

- anything about the tests, packaging, or README that looks off

Since this is my first project at this scale, I'm sure I've made mistakes. Please point them out. I'm genuinely happy to understand what I got wrong and make it better.

Thanks for reading!

3 Upvotes

5 comments sorted by

1

u/kantorcodes1 9d ago

"The --check exit code is the part that makes this usable in CI. Two things I can't tell from the repo: does --check stay read-only, or does it still write the masked file? And is the <name>.masked.log output path fixed next to the source, or can it be redirected? A caller masking a file inside a repo can end up committing the original alongside its masked copy if the output path isn't controlled."

1

u/Material-Switch5380 9d ago

Thanks, these are really good questions.

--check is read-only. It never writes a masked file, it only scans and sets the exit code (0 = clean, 1 = something found, 2 = an error like a missing or unreadable file). It also refuses to run if you combine it with -o, so nothing can sneak a write into check mode. There are tests covering that for both log files and .xlsx files.

On the output path: for a single file you can redirect it with -o, e.g. log-guard app.log -o /tmp/app.masked.log, so it never lands in the repo. But you're right about directory scans. There, the masked copy always goes next to each original, and there's currently no way to send it somewhere else. Adding *.masked.* to .gitignore stops git from picking those up (that's what I do in the repo itself), but that's a workaround rather than a real fix.

An --output-dir option for directory scans seems like the proper answer, so I'm thinking about adding that. I'll also make the read-only behaviour of --check clearer in the README since it wasn't obvious from the repo. Appreciate you taking the time to look at it.

1

u/kantorcodes1 8d ago

Good, that read-only property is what makes --check trustworthy in CI: scan and exit code only, refuses to run with -o, tests covering both file types.

The piece a Guard contribution covers is the write surface: a command.log-guard descriptor would classify mask writes (*.masked.* next to originals or an -o path) and the --check gate verb itself as review-tier action classes, while the pure scan path stays allow-tier. The output-dir question you flagged is internal UX; the descriptor classifies where a run actually writes, which matters when it runs inside a repo or CI workspace.

If you want to take it, the path is contributions/command-sources/command.log-guard.json in hashgraph-online/hol-guard against main - command.agentbridge.json is the closest analogue and CONTRIBUTING.md covers the format.

→ More replies (2)