-
-
Notifications
You must be signed in to change notification settings - Fork 341
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for specifying custom JSON parsers (#208)
* Added custom JSON parser * Added documentation * Forgot to add contrib doc * Added contrib to top-level module * Added community default decoder * Added pragma: no-cover
- Loading branch information
Showing
9 changed files
with
208 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
.. _contrib: | ||
|
||
=================================== | ||
Community-Contributed Functionality | ||
=================================== | ||
|
||
|
||
When maintaining ``tda-api``, the authors have two goals: make common things | ||
easy, and make uncommon things possible. This meets the needs of vast majority | ||
of the community, while allowing advanced users or those with very niche | ||
requirements to progress using potentially custom approaches. | ||
|
||
However, this philosophy explicitly excludes functionality that is potentially | ||
useful to many users, but is either not directly related to the core | ||
functionality of the API wrapper. This is where the ``contrib`` module comes | ||
into play. | ||
|
||
This module is a collection of high-quality code that was produced by the | ||
community and for the community. It includes utility methods that provide | ||
additional functionality beyond the core library, fixes for quirks in API | ||
behavior, etc. This page lists the available functionality. If you'd like to | ||
discuss this or propose/request new additions, please join our `Discord server | ||
<https://discord.gg/Ddha8cm6dx>`__. | ||
|
||
|
||
.. _custom_json_decoding: | ||
|
||
|
||
-------------------- | ||
Custom JSON Decoding | ||
-------------------- | ||
|
||
TDA's API occasionally emits invalid JSON in the stream. This class implements | ||
all known workarounds and hacks to get around these quirks: | ||
|
||
.. autoclass:: tda.contrib.util::HeuristicJsonDecoder | ||
:members: | ||
:undoc-members: | ||
|
||
You can use it as follows: | ||
|
||
.. code-block:: python | ||
from tda.contrib.util import HeuristicJsonDecoder | ||
stream_client = # ... create your stream | ||
stream_client.set_json_decoder(HeuristicJsonDecoder()) | ||
# ... continue as normal | ||
If you encounter invalid stream items that are not fixed by using this decoder, | ||
please let us know in our `Discord server <https://discord.gg/Ddha8cm6dx>`__ or | ||
follow the guide in :ref:`contributing` to add new functionality. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ | |
util | ||
example | ||
help | ||
contrib | ||
contributing | ||
|
||
Indices and tables | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import util |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import json | ||
from tda.streaming import StreamJsonDecoder | ||
|
||
|
||
class HeuristicJsonDecoder(StreamJsonDecoder): | ||
def decode_json_string(self, raw): | ||
''' | ||
Attempts the following, in order: | ||
1. Return the JSON decoding of the raw string. | ||
2. Replace all instances of ``\\\\\\\\`` with ``\\\\`` and return the | ||
decoding. | ||
Note alternative (and potentially expensive) transformations are only | ||
performed when ``JSONDecodeError`` exceptions are raised by earlier | ||
stages. | ||
''' | ||
|
||
# Note "no cover" pragmas are added pending addition of real-world test | ||
# cases which trigger this issue. | ||
|
||
try: | ||
return json.loads(raw) | ||
except json.decoder.JSONDecodeError: # pragma: no cover | ||
raw = raw.replace('\\\\', '\\') | ||
|
||
return json.loads(raw) # pragma: no cover |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import unittest | ||
|
||
from tda.contrib.util import HeuristicJsonDecoder | ||
|
||
|
||
class HeuristicJsonDecoderTest(unittest.TestCase): | ||
def test_raw_string_decodes(self): | ||
self.assertEqual(HeuristicJsonDecoder().decode_json_string( | ||
r'{"\\\\\\\\": "test"}'), | ||
{r'\\\\': 'test'}) | ||
|
||
|
||
def test_replace_backslashes(self): | ||
# TODO: Actually collect some failing use cases... | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters