Skip to content

Commit

Permalink
Merge pull request #235 from Davi0kProgramsThings/fix/refactoring
Browse files Browse the repository at this point in the history
Merge branch `Davi0kProgramsThings:fix/refactoring` into branch `bitfinexcom:master`.
  • Loading branch information
itsdeka authored Mar 5, 2024
2 parents 59c3090 + f94096b commit 3136b9c
Show file tree
Hide file tree
Showing 49 changed files with 2,223 additions and 1,685 deletions.
13 changes: 13 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[flake8]
max-line-length = 80
extend-select = B950
extend-ignore = E203,E501,E701

exclude =
__pycache__
build
dist
venv

per-file-ignores =
*/__init__.py:F401
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ A possible solution could be...
## Steps to reproduce (for bugs)
<!-- You can delete this section if you are not submitting a bug report -->

1. &nbsp;
2. &nbsp;
3. &nbsp;
1.
2.
3.

### Python version
<!-- Indicate your python version here -->
Expand Down
15 changes: 8 additions & 7 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ PR fixes the following issue:

# Checklist:

- [ ] My code follows the style guidelines of this project;
- [ ] I have performed a self-review of my code;
- [ ] I have commented my code, particularly in hard-to-understand areas;
- [ ] I have made corresponding changes to the documentation;
- [ ] My changes generate no new warnings;
- [ ] Mypy returns no errors or warnings when run on the root package;
- [ ] Pylint returns a score of 10.00/10.00 when run on the root package;
- [ ] I've done a self-review of my code;
- [ ] I've made corresponding changes to the documentation;
- [ ] I've made sure my changes generate no warnings;
- [ ] mypy returns no errors when run on the root package;
<!-- If you use pre-commit hooks you can always check off the following tasks -->
- [ ] I've run black to format my code;
- [ ] I've run isort to format my code's import statements;
- [ ] flake8 reports no errors when run on the entire code base;
9 changes: 3 additions & 6 deletions .github/workflows/bitfinex-api-py-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ on:
branches:
- master

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -23,7 +20,7 @@ jobs:
python-version: '3.8'
- name: Install bitfinex-api-py's dependencies
run: python -m pip install -r dev-requirements.txt
- name: Lint the project with pylint (and fail if score is lower than 10.00/10.00)
run: python -m pylint bfxapi
- name: Run mypy to check the correctness of type hinting (and fail if any error or warning is found)
- name: Run pre-commit hooks (see .pre-commit-config.yaml)
uses: pre-commit/[email protected]
- name: Run mypy to ensure correct type hinting
run: python -m mypy bfxapi
18 changes: 11 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
.venv
.DS_Store
.vscode
*.pyc
*.log
.python-version
__pycache__

bitfinex_api_py.egg-info
bitfinex_api_py.dist-info
build/
dist/
pip-wheel-metadata/
.eggs

__pycache__
.idea

dist
venv
!.gitkeep
MANIFEST
venv/
2 changes: 2 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[settings]
profile = black
17 changes: 17 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
repos:
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.2.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8

additional_dependencies: [
flake8-bugbear
]
25 changes: 0 additions & 25 deletions .pylintrc

This file was deleted.

43 changes: 35 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,9 @@ Contributors must uphold the [Contributor Covenant code of conduct](https://gith
1. [Installation and setup](#installation-and-setup)
* [Cloning the repository](#cloning-the-repository)
* [Installing the dependencies](#installing-the-dependencies)
* [Set up the pre-commit hooks (optional)](#set-up-the-pre-commit-hooks-optional)
2. [Before opening a PR](#before-opening-a-pr)
* [Tip](#tip)
3. [License](#license)

## Installation and setup
Expand All @@ -333,23 +335,48 @@ git clone --branch v3-beta --single-branch https://github.com/bitfinexcom/bitfin
python3 -m pip install -r dev-requirements.txt
```

Make sure to install `dev-requirements.txt` instead of `requirements.txt`. \
`dev-requirements.txt` will install all dependencies in `requirements.txt` plus any development dependencies. \
This will also install the versions in use of [`pylint`](https://github.com/pylint-dev/pylint) and [`mypy`](https://github.com/python/mypy), which you should both use before opening your PRs.
Make sure to install `dev-requirements.txt` (and not `requirements.txt`!). \
`dev-requirements.txt` will install all dependencies in `requirements.txt` plus any development dependency. \
dev-requirements includes [mypy](https://github.com/python/mypy), [black](https://github.com/psf/black), [isort](https://github.com/PyCQA/isort), [flake8](https://github.com/PyCQA/flake8), and [pre-commit](https://github.com/pre-commit/pre-commit) (more on these tools in later chapters).

All done, your Python 3.8+ environment should now be able to run `bitfinex-api-py`'s source code.

### Set up the pre-commit hooks (optional)

**Do not skip this paragraph if you intend to contribute to the project.**

This repository includes a pre-commit configuration file that defines the following hooks:
1. [isort](https://github.com/PyCQA/isort)
2. [black](https://github.com/psf/black)
3. [flake8](https://github.com/PyCQA/flake8)

To set up pre-commit use:
```console
python3 -m pre-commit install
```

These will ensure that isort, black and flake8 are run on each git commit.

[Visit this page to learn more about git hooks and pre-commit.](https://pre-commit.com/#introduction)

#### Manually triggering the pre-commit hooks

You can also manually trigger the execution of all hooks with:
```console
python3 -m pre-commit run --all-files
```

## Before opening a PR

**We won't accept your PR or we will request changes if the following requirements aren't met.**
**We won't accept your PR or we'll request changes if the following requirements aren't met.**

Wheter you're submitting a bug fix, a new feature or a documentation change, you should first discuss it in an issue.

All PRs must follow this [PULL_REQUEST_TEMPLATE](https://github.com/bitfinexcom/bitfinex-api-py/blob/v3-beta/.github/PULL_REQUEST_TEMPLATE.md) and include an exhaustive description.
You must be able to check off all tasks listed in [PULL_REQUEST_TEMPLATE](https://raw.githubusercontent.com/bitfinexcom/bitfinex-api-py/master/.github/PULL_REQUEST_TEMPLATE.md) before opening a pull request.

### Tip

Before opening a pull request, you should also make sure that:
- [ ] [`pylint`](https://github.com/pylint-dev/pylint) returns a score of 10.00/10.00 when run against your code.
- [ ] [`mypy`](https://github.com/python/mypy) doesn't throw any error code when run on the project (excluding notes).
Setting up the project's pre-commit hooks will help automate this process ([more](#set-up-the-pre-commit-hooks-optional)).

## License

Expand Down
7 changes: 1 addition & 6 deletions bfxapi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
from ._client import \
Client, \
REST_HOST, \
WSS_HOST, \
PUB_REST_HOST, \
PUB_WSS_HOST
from ._client import PUB_REST_HOST, PUB_WSS_HOST, REST_HOST, WSS_HOST, Client
50 changes: 27 additions & 23 deletions bfxapi/_client.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
from typing import \
TYPE_CHECKING, List, Optional
from typing import TYPE_CHECKING, List, Optional

from bfxapi._utils.logging import ColorLogger

from bfxapi.exceptions import IncompleteCredentialError
from bfxapi.rest import BfxRestInterface
from bfxapi.websocket import BfxWebSocketClient
from bfxapi.exceptions import IncompleteCredentialError

if TYPE_CHECKING:
from bfxapi.websocket._client.bfx_websocket_client import \
_Credentials
from bfxapi.websocket._client.bfx_websocket_client import _Credentials

REST_HOST = "https://api.bitfinex.com/v2"
WSS_HOST = "wss://api.bitfinex.com/ws/2"

PUB_REST_HOST = "https://api-pub.bitfinex.com/v2"
PUB_WSS_HOST = "wss://api-pub.bitfinex.com/ws/2"


class Client:
def __init__(
self,
api_key: Optional[str] = None,
api_secret: Optional[str] = None,
*,
rest_host: str = REST_HOST,
wss_host: str = WSS_HOST,
filters: Optional[List[str]] = None,
timeout: Optional[int] = 60 * 15,
log_filename: Optional[str] = None
self,
api_key: Optional[str] = None,
api_secret: Optional[str] = None,
*,
rest_host: str = REST_HOST,
wss_host: str = WSS_HOST,
filters: Optional[List[str]] = None,
timeout: Optional[int] = 60 * 15,
log_filename: Optional[str] = None,
) -> None:
credentials: Optional["_Credentials"] = None

if api_key and api_secret:
credentials = \
{ "api_key": api_key, "api_secret": api_secret, "filters": filters }
credentials = {
"api_key": api_key,
"api_secret": api_secret,
"filters": filters,
}
elif api_key:
raise IncompleteCredentialError( \
"You must provide both an API-KEY and an API-SECRET (missing API-KEY).")
raise IncompleteCredentialError(
"You must provide both API-KEY and API-SECRET (missing API-KEY)."
)
elif api_secret:
raise IncompleteCredentialError( \
"You must provide both an API-KEY and an API-SECRET (missing API-SECRET).")
raise IncompleteCredentialError(
"You must provide both API-KEY and API-SECRET (missing API-SECRET)."
)

self.rest = BfxRestInterface(rest_host, api_key, api_secret)

Expand All @@ -48,5 +51,6 @@ def __init__(
if log_filename:
logger.register(filename=log_filename)

self.wss = BfxWebSocketClient(wss_host, \
credentials=credentials, timeout=timeout, logger=logger)
self.wss = BfxWebSocketClient(
wss_host, credentials=credentials, timeout=timeout, logger=logger
)
11 changes: 7 additions & 4 deletions bfxapi/_utils/json_decoder.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from typing import Dict, Any
import json
import re
from typing import Any, Dict

import re, json

def _to_snake_case(string: str) -> str:
return re.sub(r"(?<!^)(?=[A-Z])", "_", string).lower()


def _object_hook(data: Dict[str, Any]) -> Any:
return { _to_snake_case(key): value for key, value in data.items() }
return {_to_snake_case(key): value for key, value in data.items()}


class JSONDecoder(json.JSONDecoder):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(object_hook=_object_hook, *args, **kwargs)
super().__init__(*args, **kwargs, object_hook=_object_hook)
24 changes: 11 additions & 13 deletions bfxapi/_utils/json_encoder.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
from typing import \
Union, List, Dict, \
Any

import json

from decimal import Decimal
from typing import Any, Dict, List, Union

_ExtJSON = Union[
Dict[str, "_ExtJSON"], List["_ExtJSON"], bool, int, float, str, Decimal, None
]

_ExtJSON = Union[Dict[str, "_ExtJSON"], List["_ExtJSON"], \
bool, int, float, str, Decimal, None]
_StrictJSON = Union[Dict[str, "_StrictJSON"], List["_StrictJSON"], int, str, None]

_StrictJSON = Union[Dict[str, "_StrictJSON"], List["_StrictJSON"], \
int, str, None]

def _clear(dictionary: Dict[str, Any]) -> Dict[str, Any]:
return { key: value for key, value in dictionary.items() \
if value is not None }
return {key: value for key, value in dictionary.items() if value is not None}


def _adapter(data: _ExtJSON) -> _StrictJSON:
if isinstance(data, bool):
Expand All @@ -25,12 +22,13 @@ def _adapter(data: _ExtJSON) -> _StrictJSON:
return format(data, "f")

if isinstance(data, list):
return [ _adapter(sub_data) for sub_data in data ]
return [_adapter(sub_data) for sub_data in data]
if isinstance(data, dict):
return _clear({ key: _adapter(value) for key, value in data.items() })
return _clear({key: _adapter(value) for key, value in data.items()})

return data


class JSONEncoder(json.JSONEncoder):
def encode(self, o: _ExtJSON) -> str:
return super().encode(_adapter(o))
Loading

0 comments on commit 3136b9c

Please sign in to comment.