Skip to content

Latest commit

 

History

History
83 lines (49 loc) · 5.74 KB

CONTRIBUTING.md

File metadata and controls

83 lines (49 loc) · 5.74 KB

Contributing

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
    • Snippets are defined in RequesterAuthOptionsCommand
    • Examples of how to use snippets should be added to documentation
  • 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!

Issues and Bugs

If you open an issue, follow the guidelines in the issue template to make the issue easier to reproduce.

Pull Requests

If you're going to submit a PR, read on for instructions on how to set up Requester for development.


Installing the pre-commit Git hook

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. This hook runs code linting and style checking with flake8, and builds the documentation from the sources in docs/_content.

Python Linting and Code Style

Uses flake8, isort, black, pyright. To install, run pip install flake8 isort black. pyright can be installed with npm or yarn.

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.

All classes and methods should have docstrings, limited to 82 characters per line. Except for run and __init__. Feel free to add comments for anything that's not obvious.

Tests

Tests are divided into tests of the core package, which depend on a mocked sublime and run on Travis, and integration tests 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 install httpbin with docker pull kennethreitz/httpbin, or pip install httpbin gunicorn. You can then run it with docker run -p 8000:80 kennethreitz/httpbin, or gunicorn httpbin:app

To run core tests, execute cd .. && python3 -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.

Docs

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.

How Does Requester Work?

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.

Parser

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.

Use of Eval and Exec

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.

Writing a New Command Class

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.