Outline of RangeStream data structure
A RangeStream is initialised by providing:
a URL (the file to be streamed)
a client (e.g.
httpx.Client)(optionally) a range, as either:
ranges.Rangefrom thepython-rangespackage [recommended]or a tuple of integers, presumed to be a half-open interval inclusive of start/exclusive of stop as is common practice in Python —
[start, stop)in interval notation
Since every range request returns the total content length, the
RangeStream will become capable of seeking to negative-valued ranges
(whose positions are in respect to the end) after fulfilling its first
range request.
If no range is provided upon initialisation then the range defaults to
[0,0), the empty range, and a request will be sent to the server for
this (valid) range, whose only result will be to set the total file
length on the _length attribute of RangeStream (accessed through
the total_bytes property).
Once a request is made for a non-empty range, the RangeStream
acquires the first entry in the RangeDict stored on the ._ranges
attribute. When using the ranges, you should access the ranges
property (instead of the internal _ranges attribute), which takes
into account whether the bytes in each range’s RangeResponse are
exhausted or removed due to overlap with another range. See the design
docs for further details.
Example
Adapted from
tests/range_stream_core_test.py(source)
from range_streams import RangeStream, _EXAMPLE_URL
stream = RangeStream(url=_EXAMPLE_URL)
stream.add(byte_range=(0,3)) # or pass ranges.Range(0,3)
stream.ranges
⇣
RangeDict{
RangeSet{Range[0, 3)}: RangeResponse ⠶ [0, 3) @ 'example_text_file.txt' from raw.githubusercontent.com
}
Further ranges are requested by simply calling RangeStream.add with
another Range object. You can also provide a byte range to the add
method as a tuple of two integers, which will be interpreted per the
usual convention for ranges in Python, as a [a,b) half-open
interval.
stream.add(byte_range=(7,9))
stream.ranges
⇣
RangeDict{
RangeSet{Range[0, 3)}: RangeResponse ⠶ [0, 3) @ 'example_text_file.txt' from raw.githubusercontent.com,
RangeSet{Range[7, 9)}: RangeResponse ⠶ [7, 9) @ 'example_text_file.txt' from raw.githubusercontent.com
}