Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: websocket-client/websocket-client
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.1
Choose a base ref
...
head repository: websocket-client/websocket-client
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.1.0
Choose a head ref

Commits on May 30, 2021

  1. Cast proxy_port to int from str

    Without casting to an int, will encounter `TypeError: an integer is required (got type str)` when using PySocks 1.7.1 to connect to a SOCKS proxy like shadowsocks (see issue #696)
    engn33r authored May 30, 2021
    Copy the full SHA
    7a70aef View commit details
  2. Copy the full SHA
    b8f4c35 View commit details
  3. Copy the full SHA
    c36d26a View commit details
  4. Fix #688 by adding to FAQ

    engn33r committed May 30, 2021
    Copy the full SHA
    62eca76 View commit details
  5. Fix CI errors

    engn33r committed May 30, 2021
    Copy the full SHA
    8a5176f View commit details

Commits on May 31, 2021

  1. Copy the full SHA
    70d7af9 View commit details
  2. Copy the full SHA
    a9630e8 View commit details
  3. Copy the full SHA
    b49c0d4 View commit details
  4. Copy the full SHA
    deceee5 View commit details
  5. Copy the full SHA
    2719f89 View commit details
  6. Add code coverage for PR #698

    engn33r committed May 31, 2021
    Copy the full SHA
    361c014 View commit details
  7. Copy the full SHA
    287970e View commit details
  8. Copy the full SHA
    b090664 View commit details
  9. Copy the full SHA
    27d97b8 View commit details

Commits on Jun 1, 2021

  1. Copy the full SHA
    7300759 View commit details

Commits on Jun 2, 2021

  1. Copy the full SHA
    60e4711 View commit details
  2. Copy the full SHA
    fcb022c View commit details

Commits on Jun 3, 2021

  1. Fix #701 update docstrings

    engn33r committed Jun 3, 2021
    Copy the full SHA
    1e1f495 View commit details

Commits on Jun 4, 2021

  1. Copy the full SHA
    494564f View commit details
  2. Copy the full SHA
    eaf1b8c View commit details
  3. Copy the full SHA
    7c9d604 View commit details
  4. Copy the full SHA
    beb135a View commit details

Commits on Jun 8, 2021

  1. Copy the full SHA
    d265ede View commit details
  2. Copy the full SHA
    a462d45 View commit details
  3. Copy the full SHA
    150df4f View commit details

Commits on Jun 9, 2021

  1. Fix spaces in README example (#704)

    There shouldn't be spaces when defining values for attributes (PEP8)
    varfigstar authored Jun 9, 2021
    Copy the full SHA
    3c7ef93 View commit details

Commits on Jun 10, 2021

  1. 1.1.0

    engn33r committed Jun 10, 2021
    Copy the full SHA
    11893bc View commit details
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -20,10 +20,10 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Build websocket-client & run tests
run: |
pip install -U pip setuptools wheel readme_renderer twine pytest PySocks
python -c "import setuptools; print('Setup tools version'); print(setuptools.__version__)"
pip3 install -U pip setuptools wheel readme_renderer twine pytest PySocks
python3 -c "import setuptools; print('Setup tools version'); print(setuptools.__version__)"
pytest websocket/tests -v -rP
python setup.py sdist
python3 setup.py sdist
twine check dist/*
env:
TEST_WITH_INTERNET: 1
23 changes: 9 additions & 14 deletions .github/workflows/codecoverage.yml
Original file line number Diff line number Diff line change
@@ -12,28 +12,23 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: "3.9"
- name: Run test cases without internet to verify no offline test failures
- name: Run test cases without internet to verify no offline test failures and cover non-wsaccel functions
run: |
pip install coverage pytest pytest-cov setuptools PySocks
python -c "import setuptools; print('Setup tools version'); print(setuptools.__version__)"
python setup.py install
pip3 install coverage pytest pytest-cov setuptools PySocks
python3 -c "import setuptools; print('Setup tools version'); print(setuptools.__version__)"
python3 setup.py install
pytest -vrP --cov=websocket websocket/tests --cov-config=.coveragerc
coverage report
- name: Run test_abnf.py without numpy
- name: Install wsaccel, then run all test cases for coverage collection
run: |
pip uninstall numpy
pytest -vrP --cov=websocket websocket/tests/test_abnf.py --cov-config=.coveragerc --cov-append
env:
TEST_WITH_INTERNET: 1
- name: Install numpy, then run test cases for coverage collection
run: |
pip install numpy
pip3 install wsaccel
pytest -vrP --cov=websocket websocket/tests --cov-config=.coveragerc --cov-append
coverage report
env:
TEST_WITH_INTERNET: 1
- name: Run with extra environment variable and create report
- name: Run SSL test with extra environment variable and create report
run: |
python -c "import ssl; print(ssl.get_default_verify_paths().capath)"
python3 -c "import ssl; print(ssl.get_default_verify_paths().capath)"
pytest -vrP --cov=websocket websocket/tests --cov-config=.coveragerc --cov-append -k "testSSLopt"
coverage xml
env:
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -16,9 +16,9 @@ jobs:

- name: Perform mandatory flake8 linting
run: |
pip install flake8
pip3 install flake8
flake8 --version
flake8 . --count --select=E11,E12,E22,E25,E26,E3,E71,E9,F63,F7,F82,F84,W3,W503 --ignore=F821 --show-source --statistics
flake8 . --builtins=FileNotFoundError --count --select=E11,E12,E22,E25,E26,E3,E71,E9,F63,F7,F82,F84,W3,W503 --show-source --statistics
- name: Perform optional exit-zero flake8 linting
run: |
12 changes: 11 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
ChangeLog
============

- 1.1.0
- Set enable_multithread to True by default (beb135a)
- Performance improvement in _mask() function (287970e, #433)
- Performance improvement in recv_strict() function (60e4711, #255)
- Performance improvement by removing numpy-related code (a462d45)
- Support uppercase no_proxy, http_proxy, https_proxy env vars (150df4f, #700)
- Add sslopt 'server_hostname' support (#698)
- Replace deprecated ssl.PROTOCOL_SSLv23 with ssl.PROTOCOL_TLS (494564f)
- Update documentation, README (7c9d604, #704)

- 1.0.1
- Fix exception handling bug #694

@@ -10,7 +20,7 @@ ChangeLog
- Use semver for release versions, unlike breaking release 0.58.0 (#669)
- Enhance enableTrace output (13e83b4)
- Improve unit tests to over 80% code coverage (1679ab0, a00dd2d, etc.)
- Fix old _app.py close status code bug (#686)
- Fix old _app.py close status code bug (resulted in on_close() requiring 3 args) (#686)
- Replace select import with selectors (#568)

- 0.59.0
27 changes: 16 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -37,12 +37,17 @@ support (RFC 7692) and [minimal threading documentation/support](https://websock

## Performance

The `send` and `validate_utf8` methods are very slow in pure Python. You can
disable UTF8 validation in this library (and receive a performance enhancement)
with the `skip_utf8_validation` parameter. If you want to get better
performance, please install both numpy and wsaccel, and import them into your
project files - these other libraries will automatically be used when available.
Note that wsaccel can sometimes cause other issues.
The `send` and `validate_utf8` methods can sometimes be bottleneck.
You can disable UTF8 validation in this library (and receive a
performance enhancement) with the `skip_utf8_validation` parameter.
If you want to get better performance, install wsaccel. While
websocket-client does not depend on wsaccel, it will be used if
available. wsaccel doubles the speed of UTF8 validation and
offers a very minor 10% performance boost when masking the
payload data as part of the `send` process. Numpy used to
be a suggested performance enhancement alternative, but
[issue #687](https://github.com/websocket-client/websocket-client/issues/687)
found it didn't help.

## Examples

@@ -69,7 +74,7 @@ def on_message(ws, message):
def on_error(ws, error):
print(error)

def on_close(ws):
def on_close(ws, close_status_code, close_msg):
print("### closed ###")

def on_open(ws):
@@ -85,10 +90,10 @@ def on_open(ws):
if __name__ == "__main__":
websocket.enableTrace(True)
ws = websocket.WebSocketApp("ws://echo.websocket.org/",
on_open = on_open,
on_message = on_message,
on_error = on_error,
on_close = on_close)
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close)

ws.run_forever()
```
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ def setup(app):
author = 'liris'

# The full version, including alpha/beta/rc tags
release = '1.0.1'
release = '1.1.0'


# -- General configuration ---------------------------------------------------
23 changes: 20 additions & 3 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
@@ -356,11 +356,13 @@ by default. You may encounter problems if using SSL/TLS with your proxy.
`Work in progress - coming soon`


Using Unix Domain Sockets
Connecting with Custom Sockets
--------------------------------

You can also connect to a WebSocket server hosted on a unix domain socket.
Just use the ``socket`` option when creating your connection.
You can also connect to a WebSocket server hosted on a
specific socket using the ``socket`` option when
creating your connection. Below is an example of using
a unix domain socket.

::

@@ -373,6 +375,21 @@ Just use the ``socket`` option when creating your connection.
socket = my_socket,
sockopt=((socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),))

Other socket types can also be used. The following example
is for a AF_INET (IP address) socket.

::

import socket
from websocket import create_connection
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_socket.bind(("172.18.0.1", 3002))
my_socket.connect()

ws = create_connection("ws://127.0.0.1/", # Dummy URL
socket = my_socket)


Post-connection features
==========================

48 changes: 44 additions & 4 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
@@ -14,10 +14,40 @@ Why is this library slow?
The ``send`` and ``validate_utf8`` methods are very slow in pure Python.
You can disable UTF8 validation in this library (and receive a
performance enhancement) with the ``skip_utf8_validation`` parameter.
If you want to get better performance, please install both numpy and
wsaccel, and import them into your project files - these external
libraries will automatically be used when available. Note that
wsaccel can sometimes cause other issues.
If you want to get better performance, install wsaccel. While
websocket-client does not depend on wsaccel, it will be used if
available. wsaccel doubles the speed of UTF8 validation and
offers a very minor 10% performance boost when masking the
payload data as part of the ``send`` process. Numpy used to
be a suggested alternative, but
`issue #687 <https://github.com/websocket-client/websocket-client/issues/687>`_
found it didn't help.

How to troubleshoot an unclear callback error?
===================================================

To get more information about a callback error, you can
specify a custom ``on_error()`` function that raises errors
to provide more information. Sample code of such a solution
is shown below, although the example URL provided will probably
not trigger an error under normal circumstances.
`Issue #377 <https://github.com/websocket-client/websocket-client/issues/60>`_
discussed this topic previously.

::

import websocket

def on_message(ws, message):
print(message)

def on_error(wsapp, err):
print("Got a an error: ", err)

wsapp = websocket.WebSocketApp("ws://echo.websocket.org/",
on_message = on_message,
on_error=on_error)
wsapp.run_forever()

How to solve the "connection is already closed" error?
===========================================================
@@ -80,6 +110,16 @@ solution for the server is to treat each connection separately, unless
the WebSocket uses an authentication method to identify individual clients
connecting to the server.

What is the difference between recv_frame(), recv_data_frame(), and recv_data()?
==================================================================================

This is explained in
`issue #688 <https://github.com/websocket-client/websocket-client/issues/688>`_.
This information is useful if you do NOT want to use ``run.forever()`` but want
to have similar functionality. In short, ``recv_data()`` is the
recommended choice and you will need to manage ping/pong on your own, while
``run.forever()`` handles ping/pong by default.

How to disable ssl cert verification?
=======================================

72 changes: 45 additions & 27 deletions docs/source/threading.rst
Original file line number Diff line number Diff line change
@@ -2,19 +2,31 @@
Threading
#########

*Warning:* The thread management documentation for this project is somewhat lacking.
If asynchronous threading is a critical part of you project, you may
want to investigate a more robust solution.

Multithreading in the websocket-client library is handled using the ``threading``
module. You can see ``import threading`` in some of this project's
code. The
`echoapp_client.py example <https://github.com/websocket-client/websocket-client/blob/master/examples/echoapp_client.py>`_.
is a good illustration of how threading can be used in the websocket-client library.
Importance of enable_multithread
======================================

The ``enable_multithread`` variable should be set to ``True`` when
working with multiple threads. If ``enable_multithread`` is not
set to ``True``, websocket-client will act asynchronously and
not be thread safe. This variable should be enabled by default
starting with the 1.1.0 release, but had a default value of ``False``
in older versions. See issues
`#591 <https://github.com/websocket-client/websocket-client/issues/591>`_
and
`#507 <https://github.com/websocket-client/websocket-client/issues/507>`_
for related issues.

asyncio library usage
=======================
Issue `#496 <https://github.com/websocket-client/websocket-client/issues/496>`_
indicates that websocket-client is not compatible with asyncio. However, some simple
use cases, such as asyncronously receiving data, may be a convenient place to use asyncio.
The following code snippet shows how asyncronous listening might be implemented.
indicates that websocket-client is not compatible with asyncio. The
`engine-io project <https://github.com/miguelgrinberg/python-engineio/>`_,
which is used in a popular socket-io client, specifically uses websocket-client
as a dependency only in places where asyncio is not used. If asyncio is an
important part of your project, you might consider using another websockets library.
However, some simple use cases, such as asyncronously receiving data, may be
a place to use asyncio. Here is one snippet showing how asyncronous listening
might be implemented.

::

@@ -23,21 +35,30 @@ The following code snippet shows how asyncronous listening might be implemented.
return result


The ``enable_multithread`` variable is also a factor when handling multiple threads.
When using WebSocketApp, ``enable_multithread`` is only set
`when ping_interval is set <https://github.com/websocket-client/websocket-client/blob/7466b961f68bda3c17d2aa4701fd145abf3474ed/websocket/_app.py#L290>`_.
When WebSocketApp is not used, ``enable_multithread`` can be set to a user-specified value, and this value
will `determine the thread locking <https://github.com/websocket-client/websocket-client/blob/7466b961f68bda3c17d2aa4701fd145abf3474ed/websocket/_core.py#L103>`_.
threading library usage
==========================

The websocket-client library has some built-in threading support
provided by the ``threading`` library. You will see ``import threading``
in some of this project's code. The
`echoapp_client.py example <https://github.com/websocket-client/websocket-client/blob/master/examples/echoapp_client.py>`_
is a good illustration of how ``threading`` can be used in the websocket-client library.
Another example is found in
`an external site's documentation <https://support.kraken.com/hc/en-us/articles/360043283472-Python-WebSocket-Recommended-Python-library-and-usage-examples>`_,
which demonstrates using the _thread library, which is lower level than
the threading library.

Possible issues with threading
==================================

Further investigation into using the ``threading`` module is seen in
issue `#612 <https://github.com/websocket-client/websocket-client/issues/612>`_
which illustrates on situation where using the threading module can impact
which illustrates one situation where using the threading module can impact
the observed behavior of this library. The first code example below does
not trigger the on_close() function, but the second code example does
trigger the on_close() function. The highlighted rows show the lines
added exclusively in the second example. This threading approach is identical
to the `echoapp_client.py example <https://github.com/websocket-client/websocket-client/blob/master/examples/echoapp_client.py>`_.
not trigger the ``on_close()`` function, but the second code example does
trigger the ``on_close()`` function. The highlighted rows show the lines added
exclusively in the second example. This threading approach is identical to the
`echoapp_client.py example <https://github.com/websocket-client/websocket-client/blob/master/examples/echoapp_client.py>`_.
However, further testing found that some WebSocket servers, such as
ws://echo.websocket.org, do not trigger the ``on_close()`` function.

@@ -58,7 +79,7 @@ ws://echo.websocket.org, do not trigger the ``on_close()`` function.
ws.close()
print("Message received...")

def on_close(ws):
def on_close(ws, close_status_code, close_msg):
print(">>>>>>CLOSED")

wsapp = websocket.WebSocketApp("wss://api.bitfinex.com/ws/1", on_open=on_open, on_message=on_message, on_close=on_close)
@@ -86,15 +107,12 @@ ws://echo.websocket.org, do not trigger the ``on_close()`` function.
threading.Thread(target=run).start()
def on_close(ws):
def on_close(ws, close_status_code, close_msg):
print(">>>>>>CLOSED")
wsapp = websocket.WebSocketApp("wss://api.bitfinex.com/ws/1", on_open=on_open, on_message=on_message, on_close=on_close)
wsapp.run_forever()
TODO: Add an example of using ws.recv() in a non-blocking manner, as asked in
`issue #416 <https://github.com/websocket-client/websocket-client/issues/416>`_

In part because threading is hard, but also because this project has (until recently)
lacked any threading documentation, there are many issues on this topic, including:

2 changes: 1 addition & 1 deletion examples/echoapp_client.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ def on_error(ws, error):
print(error)


def on_close(ws):
def on_close(ws, close_status_code, close_msg):
print("### closed ###")


2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@
from setuptools import setup
import pkg_resources

VERSION = "1.0.1"
VERSION = "1.1.0"

install_requires = []
tests_require = []
2 changes: 1 addition & 1 deletion websocket/__init__.py
Original file line number Diff line number Diff line change
@@ -25,4 +25,4 @@
from ._logging import *
from ._socket import *

__version__ = "1.0.1"
__version__ = "1.1.0"
Loading