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.Range
from thepython-ranges
package [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
}