This document is meant for developers and provides instruction on how to work with the repository.
This project requires Lefthook and Commitlint.
Install lefthook:
lefthook installAlso install direnv to benefit from some dev tools.
To update locked dependencies, run
uv syncFrom time to time, check if the major versions of dependencies in
pyproject.toml need updating.
To run tests, use testall.
To run tests and check for coverage, use coverage.
I name all Click commands starting with an entity, e.g., “BCGE,” followed by the action, e.g., “fetch.”
There are plenty of commands that do not follow this naming scheme. That’s OK, they are legacy commands. I don’t think it’s worth the effort to update them.
I need to use a browser automation technology, and I decided to use Playwright:
- Playwright comes with a code generator tool.
- I found that Playwright comes with more relevant functionality, e.g., capturing downloads.
- Playwright’s async support makes code more readable and easier to work with.
This app has previously used 1Password CLI, op. It should now use the
SDK, because:
- A dedicated Python library is more reliable and simpler than calling an external binary and parsing its output.
- The app is more self-contained: the SDK can be downloaded as a dependency and I don’t need to separately install the CLI.
This app has previously used a 1Password service account token saved in the config file. I decided against that. The app has to never use the token in such a way or a similar one in which it can be intercepted by other apps, e.g.,
- No saving to a file on a disk.
- No saving the secret to environment variables (subprocesses can see it then).
This is a security measure to limit the attack surface.
Fetcher can either fetch the token through 1Password directly or ask the caller to provide it at runtime (e.g., through a prompt). Delegate secret management up the stack.
I keep all secrets in 1Password for the similar reasons as above: namely, to limit the attack surface and secret-management complexity.
The secrets are even things like an OAuth token fetched by schwab-py.