Please do! Some possible improvements:
- Snippets and examples for more auth schemes
- Remember, Requester can import any Python package
- OAuth 2, using
requests-oauthlib - Other common auth protocols, using whichever package is best
- OAuth 2, using
- Snippets are defined in
RequesterAuthOptionsCommand - Examples of how to use snippets should be added to documentation
- Remember, Requester can import any Python package
- More export/import formats
- HTTP
- Look at
commands/import_export.py
- Randomized requests with benchmark runs (e.g. for fuzz testing)
- Execute all requests constructed from an iterable?
- Improve architecture and test coverage
- More pure functions, fewer coupling points to Sublime Text API
- Test coverage for syntax files
- Tell your friends about Requester!
If you open an issue, follow the guidelines in the issue template to make the issue easier to reproduce.
If you're going to submit a PR, read on for instructions on how to set up Requester for development.
Run cd .git/hooks && ln -s -f ../../docs/_hooks/* ./ from the root of the repo. This creates a symlink from the .git/hooks directory to Requester's pre-commit hook, which builds the documentation from the sources in docs/_content.
Run cd .git/hooks && ln -s -f ../../pre-push ./ from the root of the repo to also install the pre-push hook (see below).
Uses ruff (linting and formatting), installed as a uv tool with uv tool install ruff, and pyright (type checking) — install however you like (npm, uv tool install pyright, etc.), just make sure it's on your PATH.
pyright type-checks against the real Sublime Text API via sublime-text-stubs, a PEP 561 stub-only package — not vendored .pyi files. Run uv sync once after cloning to create a local .venv with the stubs installed; pyrightconfig.json points pyright at that venv. The venv is gitignored and never committed.
As long as you installed Requester's pre-push hook (see above), you will be unable to push anything that doesn't pass validation under these tools.
Tests are divided into tests of the core package, which depend on a mocked sublime and can run in CI, and integration tests that run within Sublime Text.
Many tests for Requester are asynchronous, because they depend on responses coming back before examining response tabs. For this reason, tests are executed against a local server powered by httpbin. You can run httpbin with docker pull kennethreitz/httpbin && docker run -p 8000:80 kennethreitz/httpbin, or, without Docker, uv tool run --with httpbin gunicorn httpbin:app.
To run core tests, execute cd .. && uv run python -m unittest Requester.tests.core -v && cd Requester from the root of the repo. If you don't cd into the package's parent directory, you'll run into this issue.
To run the integration tests, install UnitTesting via Package Control. Read more about UnitTesting. Also, make sure you've cloned the Requester repo into your Packages directory.
Run integration tests before committing changes. Look for UnitTesting in the command palette, hit Enter, and type Requester. Or, if you've created a project for Requester, run UnitTesting: Test Current Package.
README.md is generated by Requester's pre-commit hook. If you want to improve the docs, don't edit README.md. The correct file is docs/_content/body.md.
The core API is defined in modules under the core directory. The main class is RequestCommandMixin.
This mixin is the motor for parsing an env, executing requests in parallel in the context of this env, invoking activity indicator methods, and invoking response handling methods. These methods can be overridden to control the behavior of classes that inherit from this mixin.
The mixin uses the ResponseThreadPool class, which wraps a thread pool to execute requests in parallel. Default concurrency is determined by the mixin's MAX_WORKERS class property. The thread pool is inspected at regular intervals to remove completed responses and handle them, and show activity for pending requests.
Command classes that use this mixin can override handle_response and/or handle_responses. This way they can handle responses one at a time as they are completed, or as a group when they're all finished. Each response object contains a req namedtuple with a bunch of useful properties, the res (a requests.Response object), and an err string. Responses are sorted by request parsing order.
Command classes must also override get_requests, which must return a list of request strings, for example strings parsed from the current view. To simplify this, core has a parsers module. The important parser is parse_requests. It takes a string, such as a selection from a view, and returns a list of all calls to requests in the string.
exec is used to build an environment dict from a string, in basically the same way import populates a variables dict from a module. The execed string is simply the concatenation of the env block and the env file.
eval is used in prepare_request, in conjunction with parse_args, to parse the args passed to requests.<method>. This way Requester can modify, remove, or add to these args before actually calling requests.<method>. Much of Requester's most powerful behavior derives from this ability.
If you want to write a new command class for Requester, check out how RequesterCommand works; it simply uses the mixin and overrides get_requests and handle_response.
If you want a better understanding of the details, dive into the core directory. This is where the heavy lifting is done.