Contributing
Thank you for being interested in contributing to Hishel
. We appreciate your efforts.
You can contribute by reviewing the pull requests, opening an issue, or adding a new feature.
Here I will describe the development process and the tricks that we use during the development.
Setting up
First, you should fork the Hishel so you can create your own branch and work on it.
Then you should git clone
your fork and create a new branch for your pull request.
Scripts
Hishel
provides a script directory to simplify the development process. Here is what each command does.
- scripts/install Set up the virtual environment and install all the necessary dependencies
- scripts/lint Runs linter, formatter, and unasync to enforce code style
- scripts/check Runs all the necessary checks, including linter, formatter, static type analyzer, and unasync checks
- scripts/test Runs
scripts/check
+pytest
over the coverage.
Example:
>>> ./scripts/install
>>> source ./venv/bin/activate
>>> ./scripts/test
+ ./scripts/check
+ ruff format tests hishel --diff
26 files left unchanged
+ ruff tests hishel
+ mypy tests hishel
Success: no issues found in 38 source files
+ python unasync.py --check
hishel/_async/_client.py -> hishel/_sync/_client.py
hishel/_async/_pool.py -> hishel/_sync/_pool.py
hishel/_async/_transports.py -> hishel/_sync/_transports.py
hishel/_async/_mock.py -> hishel/_sync/_mock.py
hishel/_async/_storages.py -> hishel/_sync/_storages.py
hishel/_async/__init__.py -> hishel/_sync/__init__.py
tests/_async/test_storages.py -> tests/_sync/test_storages.py
tests/_async/test_transport.py -> tests/_sync/test_transport.py
tests/_async/__init__.py -> tests/_sync/__init__.py
tests/_async/test_client.py -> tests/_sync/test_client.py
tests/_async/test_pool.py -> tests/_sync/test_pool.py
+ coverage run -m pytest tests
============================ test session starts =============================
platform linux -- Python 3.10.12, pytest-7.4.3, pluggy-1.3.0
rootdir: /home/test/programs/gitprojects/hishel
configfile: pyproject.toml
plugins: anyio-4.1.0, asyncio-0.21.1
asyncio: mode=stric`t
collected 158 items
tests/test_controller.py .......................................... [ 26%]
tests/test_headers.py ..................... [ 39%]
tests/test_lfu_cache.py ...... [ 43%]
tests/test_serializers.py ..... [ 46%]
tests/test_utils.py ........ [ 51%]
tests/_async/test_client.py .. [ 53%]
tests/_async/test_pool.py .................. [ 64%]
tests/_async/test_storages.py ........... [ 71%]
tests/_async/test_transport.py .................. [ 82%]
tests/_sync/test_client.py . [ 83%]
tests/_sync/test_pool.py ......... [ 89%]
tests/_sync/test_storages.py ........ [ 94%]
tests/_sync/test_transport.py ......... [100%]
============================ 158 passed in 2.97s =============================
Note
Some tests may fail if you don't have all the necessary services. For example, you don't have Redis to pass the integration tests, so there is a Docker compose file in the root directory to start those services.
Async and Sync
Like HTTP Core
, Hishel
also uses the unasync strategy to support both async and sync code.
The idea behind unasync
is that you are writing only async code and also using some logic that converts your async code to sync code rather than writing almost the same code twice.
In Hishel
, there is a unasync.py
script that converts an async directory to a sync one.
Warning
You should not write any code in the hishel/_sync
directory. It is always generated by the unasync.py
scripts, and after running CI, all your changes to that directory would be lost.
Unasync scripts would automatically be called from scripts/lint
, so you should just write an async code and then call scripts/lint
.