Compare commits
34 Commits
2a00724823
...
7d173c2d3c
| Author | SHA1 | Date |
|---|---|---|
|
|
7d173c2d3c | |
|
|
ce4a76d3d2 | |
|
|
c6e29eb592 | |
|
|
c6753e2c52 | |
|
|
f4402675a6 | |
|
|
7351f08d13 | |
|
|
10477ef086 | |
|
|
c2940600dd | |
|
|
57bc184f94 | |
|
|
91cc135699 | |
|
|
ccba2e89fb | |
|
|
a0d24634f3 | |
|
|
d5da993b0a | |
|
|
e3052ad3c0 | |
|
|
4d394a1897 | |
|
|
8620c0fd45 | |
|
|
bfe349f8fd | |
|
|
31bf5f55d0 | |
|
|
adf1b18d82 | |
|
|
025d3573e1 | |
|
|
1fa68181df | |
|
|
f78362b2e4 | |
|
|
5ff1a9ca45 | |
|
|
ca9b1f80fe | |
|
|
6f828ca379 | |
|
|
fe207a69a8 | |
|
|
758251e252 | |
|
|
6834dd4ce6 | |
|
|
7f62e75111 | |
|
|
d404568ff3 | |
|
|
d4fbfaae45 | |
|
|
52e65dbe0d | |
|
|
8b3365a249 | |
|
|
2ceec5b9c0 |
|
|
@ -102,7 +102,6 @@ ENV/
|
||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
.vscode/settings.json
|
|
||||||
|
|
||||||
# all files under
|
# all files under
|
||||||
.git/
|
.git/
|
||||||
|
|
@ -122,6 +121,9 @@ Session.vim
|
||||||
# wtv git hosting service tho?
|
# wtv git hosting service tho?
|
||||||
gitea/
|
gitea/
|
||||||
|
|
||||||
|
# ------ tina-land ------
|
||||||
|
.vscode/settings.json
|
||||||
|
|
||||||
# ------ macOS ------
|
# ------ macOS ------
|
||||||
# Finder metadata
|
# Finder metadata
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
|
|
|
||||||
|
|
@ -203,9 +203,13 @@ async def stream_messages(
|
||||||
yield 'trade', piker_quote
|
yield 'trade', piker_quote
|
||||||
|
|
||||||
|
|
||||||
def make_sub(pairs: list[str], sub_name: str, uid: int) -> dict[str, str]:
|
def make_sub(
|
||||||
|
pairs: list[str],
|
||||||
|
sub_name: str,
|
||||||
|
uid: int,
|
||||||
|
) -> dict[str, str]:
|
||||||
'''
|
'''
|
||||||
Create a request subscription packet dict.
|
Create a request subscription packet `dict`.
|
||||||
|
|
||||||
- spot:
|
- spot:
|
||||||
https://binance-docs.github.io/apidocs/spot/en/#live-subscribing-unsubscribing-to-streams
|
https://binance-docs.github.io/apidocs/spot/en/#live-subscribing-unsubscribing-to-streams
|
||||||
|
|
@ -332,7 +336,8 @@ async def get_mkt_info(
|
||||||
# TODO: handle coinm futes which have a margin asset that
|
# TODO: handle coinm futes which have a margin asset that
|
||||||
# is some crypto token!
|
# is some crypto token!
|
||||||
# https://binance-docs.github.io/apidocs/delivery/en/#exchange-information
|
# https://binance-docs.github.io/apidocs/delivery/en/#exchange-information
|
||||||
or 'btc' in venue_lower
|
or
|
||||||
|
'btc' in venue_lower
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -343,12 +348,14 @@ async def get_mkt_info(
|
||||||
|
|
||||||
if (
|
if (
|
||||||
venue
|
venue
|
||||||
and 'spot' not in venue_lower
|
and
|
||||||
|
'spot' not in venue_lower
|
||||||
|
|
||||||
# XXX: catch all in case user doesn't know which
|
# XXX: catch all in case user doesn't know which
|
||||||
# venue they want (usdtm vs. coinm) and we can choose
|
# venue they want (usdtm vs. coinm) and we can choose
|
||||||
# a default (via config?) once we support coin-m APIs.
|
# a default (via config?) once we support coin-m APIs.
|
||||||
or 'perp' in venue_lower
|
or
|
||||||
|
'perp' in venue_lower
|
||||||
):
|
):
|
||||||
if not mkt_mode:
|
if not mkt_mode:
|
||||||
mkt_mode: str = f'{venue_lower}_futes'
|
mkt_mode: str = f'{venue_lower}_futes'
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
--------------
|
--------------
|
||||||
more or less the "everything broker" for traditional and international
|
more or less the "everything broker" for traditional and international
|
||||||
markets. they are the "go to" provider for automatic retail trading
|
markets. they are the "go to" provider for automatic retail trading
|
||||||
and we interface to their APIs using the `ib_insync` project.
|
and we interface to their APIs using the `ib_async` project.
|
||||||
|
|
||||||
status
|
status
|
||||||
******
|
******
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ Sub-modules within break into the core functionalities:
|
||||||
- ``broker.py`` part for orders / trading endpoints
|
- ``broker.py`` part for orders / trading endpoints
|
||||||
- ``feed.py`` for real-time data feed endpoints
|
- ``feed.py`` for real-time data feed endpoints
|
||||||
- ``api.py`` for the core API machinery which is ``trio``-ized
|
- ``api.py`` for the core API machinery which is ``trio``-ized
|
||||||
wrapping around ``ib_insync``.
|
wrapping around `ib_async`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from .api import (
|
from .api import (
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ def load_flex_trades(
|
||||||
|
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
|
|
||||||
from ib_insync import flexreport, util
|
from ib_async import flexreport, util
|
||||||
|
|
||||||
conf = get_config()
|
conf = get_config()
|
||||||
|
|
||||||
|
|
@ -154,8 +154,7 @@ def load_flex_trades(
|
||||||
trade_entries,
|
trade_entries,
|
||||||
)
|
)
|
||||||
|
|
||||||
ledger_dict: dict | None = None
|
ledger_dict: dict|None
|
||||||
|
|
||||||
for acctid in trades_by_account:
|
for acctid in trades_by_account:
|
||||||
trades_by_id = trades_by_account[acctid]
|
trades_by_id = trades_by_account[acctid]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ runnable script-programs.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
import asyncio
|
||||||
from datetime import ( # noqa
|
from datetime import ( # noqa
|
||||||
datetime,
|
datetime,
|
||||||
date,
|
date,
|
||||||
|
|
@ -140,7 +141,8 @@ async def data_reset_hack(
|
||||||
except (
|
except (
|
||||||
OSError, # no VNC server avail..
|
OSError, # no VNC server avail..
|
||||||
PermissionError, # asyncvnc pw fail..
|
PermissionError, # asyncvnc pw fail..
|
||||||
):
|
) as _vnc_err:
|
||||||
|
vnc_err = _vnc_err
|
||||||
try:
|
try:
|
||||||
import i3ipc # noqa (since a deps dynamic check)
|
import i3ipc # noqa (since a deps dynamic check)
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
|
|
@ -166,14 +168,22 @@ async def data_reset_hack(
|
||||||
|
|
||||||
# localhost but no vnc-client or it borked..
|
# localhost but no vnc-client or it borked..
|
||||||
else:
|
else:
|
||||||
try_xdo_manual(client)
|
log.error(
|
||||||
|
'VNC CLICK HACK FAILE with,\n'
|
||||||
|
f'{vnc_err!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# breakpoint()
|
||||||
|
# try_xdo_manual(client)
|
||||||
|
|
||||||
case 'i3ipc_xdotool':
|
case 'i3ipc_xdotool':
|
||||||
try_xdo_manual(client)
|
try_xdo_manual(client)
|
||||||
# i3ipc_xdotool_manual_click_hack()
|
# i3ipc_xdotool_manual_click_hack()
|
||||||
|
|
||||||
case _ as tech:
|
case _ as tech:
|
||||||
raise RuntimeError(f'{tech} is not supported for reset tech!?')
|
raise RuntimeError(
|
||||||
|
f'{tech!r} is not supported for reset tech!?'
|
||||||
|
)
|
||||||
|
|
||||||
# we don't really need the ``xdotool`` approach any more B)
|
# we don't really need the ``xdotool`` approach any more B)
|
||||||
return True
|
return True
|
||||||
|
|
@ -265,14 +275,39 @@ async def vnc_click_hack(
|
||||||
# 640x1800
|
# 640x1800
|
||||||
await client.move(
|
await client.move(
|
||||||
Point(
|
Point(
|
||||||
500,
|
500, # x from left
|
||||||
500,
|
400, # y from top
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
# in case a prior dialog win is open/active.
|
||||||
|
await client.press('ISO_Enter')
|
||||||
|
|
||||||
# ensure the ib-gw window is active
|
# ensure the ib-gw window is active
|
||||||
await client.click(MOUSE_BUTTON_LEFT)
|
await client.click(MOUSE_BUTTON_LEFT)
|
||||||
|
|
||||||
# send the hotkeys combo B)
|
# send the hotkeys combo B)
|
||||||
await client.press('Ctrl', 'Alt', key) # keys are stacked
|
await client.press(
|
||||||
|
'Ctrl',
|
||||||
|
'Alt',
|
||||||
|
key,
|
||||||
|
) # NOTE, keys are stacked
|
||||||
|
|
||||||
|
# XXX, sometimes a dialog asking if you want to "simulate
|
||||||
|
# a reset" will show, in which case we want to select
|
||||||
|
# "Yes" (by tabbing) and then hit enter.
|
||||||
|
iters: int = 1
|
||||||
|
delay: float = 0.3
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
for i in range(iters):
|
||||||
|
log.info(f'Sending TAB {i}')
|
||||||
|
await client.press('Tab')
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
for i in range(iters):
|
||||||
|
log.info(f'Sending ENTER {i}')
|
||||||
|
await client.press('KP_Enter')
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
def i3ipc_fin_wins_titled(
|
def i3ipc_fin_wins_titled(
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Core API client machinery; mostly sane/useful wrapping around `ib_insync`..
|
Core API client machinery; mostly sane/useful wrapping around
|
||||||
|
`ib_async`..
|
||||||
|
|
||||||
'''
|
'''
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
@ -57,7 +58,7 @@ from pendulum import (
|
||||||
Interval,
|
Interval,
|
||||||
)
|
)
|
||||||
from eventkit import Event
|
from eventkit import Event
|
||||||
from ib_insync import (
|
from ib_async import (
|
||||||
client as ib_client,
|
client as ib_client,
|
||||||
IB,
|
IB,
|
||||||
Contract,
|
Contract,
|
||||||
|
|
@ -143,7 +144,7 @@ _bar_sizes = {
|
||||||
_show_wap_in_history: bool = False
|
_show_wap_in_history: bool = False
|
||||||
|
|
||||||
# overrides to sidestep pretty questionable design decisions in
|
# overrides to sidestep pretty questionable design decisions in
|
||||||
# ``ib_insync``:
|
# ``ib_async``:
|
||||||
class NonShittyWrapper(Wrapper):
|
class NonShittyWrapper(Wrapper):
|
||||||
def tcpDataArrived(self):
|
def tcpDataArrived(self):
|
||||||
"""Override time stamps to be floats for now.
|
"""Override time stamps to be floats for now.
|
||||||
|
|
@ -183,7 +184,7 @@ class NonShittyIB(IB):
|
||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
# override `ib_insync` internal loggers so we can see wtf
|
# override `ib_async` internal loggers so we can see wtf
|
||||||
# it's doing..
|
# it's doing..
|
||||||
self._logger = get_logger(
|
self._logger = get_logger(
|
||||||
name=__name__,
|
name=__name__,
|
||||||
|
|
@ -194,7 +195,7 @@ class NonShittyIB(IB):
|
||||||
self.wrapper = NonShittyWrapper(self)
|
self.wrapper = NonShittyWrapper(self)
|
||||||
self.client = ib_client.Client(self.wrapper)
|
self.client = ib_client.Client(self.wrapper)
|
||||||
self.client._logger = get_logger(
|
self.client._logger = get_logger(
|
||||||
name='ib_insync.client',
|
name='ib_async.client',
|
||||||
)
|
)
|
||||||
|
|
||||||
# self.errorEvent += self._onError
|
# self.errorEvent += self._onError
|
||||||
|
|
@ -560,7 +561,7 @@ class Client:
|
||||||
# f'Recursing for more bars:\n'
|
# f'Recursing for more bars:\n'
|
||||||
)
|
)
|
||||||
# XXX, debug!
|
# XXX, debug!
|
||||||
breakpoint()
|
# breakpoint()
|
||||||
# XXX ? TODO? recursively try to re-request?
|
# XXX ? TODO? recursively try to re-request?
|
||||||
# => i think *NO* right?
|
# => i think *NO* right?
|
||||||
#
|
#
|
||||||
|
|
@ -767,25 +768,48 @@ class Client:
|
||||||
expiry: str = '',
|
expiry: str = '',
|
||||||
front: bool = False,
|
front: bool = False,
|
||||||
|
|
||||||
) -> Contract:
|
) -> Contract|list[Contract]:
|
||||||
'''
|
'''
|
||||||
Get an unqualifed contract for the current "continous"
|
Get an unqualifed contract for the current "continous"
|
||||||
future.
|
future.
|
||||||
|
|
||||||
|
When input params result in a so called "ambiguous contract"
|
||||||
|
situation, we return the list of all matches provided by,
|
||||||
|
|
||||||
|
`IB.qualifyContractsAsync(..., returnAll=True)`
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# it's the "front" contract returned here
|
# it's the "front" contract returned here
|
||||||
if front:
|
if front:
|
||||||
con = (await self.ib.qualifyContractsAsync(
|
cons = (
|
||||||
ContFuture(symbol, exchange=exchange)
|
await self.ib.qualifyContractsAsync(
|
||||||
))[0]
|
ContFuture(symbol, exchange=exchange),
|
||||||
|
returnAll=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
con = (await self.ib.qualifyContractsAsync(
|
cons = (
|
||||||
|
await self.ib.qualifyContractsAsync(
|
||||||
Future(
|
Future(
|
||||||
symbol,
|
symbol,
|
||||||
exchange=exchange,
|
exchange=exchange,
|
||||||
lastTradeDateOrContractMonth=expiry,
|
lastTradeDateOrContractMonth=expiry,
|
||||||
|
),
|
||||||
|
returnAll=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
con = cons[0]
|
||||||
|
if isinstance(con, list):
|
||||||
|
log.warning(
|
||||||
|
f'{len(con)!r} futes cons matched for input params,\n'
|
||||||
|
f'symbol={symbol!r}\n'
|
||||||
|
f'exchange={exchange!r}\n'
|
||||||
|
f'expiry={expiry!r}\n'
|
||||||
|
f'\n'
|
||||||
|
f'cons:\n'
|
||||||
|
f'{con!r}\n'
|
||||||
)
|
)
|
||||||
))[0]
|
|
||||||
|
|
||||||
return con
|
return con
|
||||||
|
|
||||||
|
|
@ -878,7 +902,7 @@ class Client:
|
||||||
currency='USD',
|
currency='USD',
|
||||||
exchange='PAXOS',
|
exchange='PAXOS',
|
||||||
)
|
)
|
||||||
# XXX, on `ib_insync` when first tried this,
|
# XXX, on `ib_async` when first tried this,
|
||||||
# > Error 10299, reqId 141: Expected what to show is
|
# > Error 10299, reqId 141: Expected what to show is
|
||||||
# > AGGTRADES, please use that instead of TRADES.,
|
# > AGGTRADES, please use that instead of TRADES.,
|
||||||
# > contract: Crypto(conId=479624278, symbol='BTC',
|
# > contract: Crypto(conId=479624278, symbol='BTC',
|
||||||
|
|
@ -910,11 +934,17 @@ class Client:
|
||||||
)
|
)
|
||||||
exch = 'SMART' if not exch else exch
|
exch = 'SMART' if not exch else exch
|
||||||
|
|
||||||
|
if isinstance(con, list):
|
||||||
|
contracts: list[Contract] = con
|
||||||
|
else:
|
||||||
contracts: list[Contract] = [con]
|
contracts: list[Contract] = [con]
|
||||||
|
|
||||||
if qualify:
|
if qualify:
|
||||||
try:
|
try:
|
||||||
contracts: list[Contract] = (
|
contracts: list[Contract] = (
|
||||||
await self.ib.qualifyContractsAsync(con)
|
await self.ib.qualifyContractsAsync(
|
||||||
|
*contracts
|
||||||
|
)
|
||||||
)
|
)
|
||||||
except RequestError as err:
|
except RequestError as err:
|
||||||
msg = err.message
|
msg = err.message
|
||||||
|
|
@ -992,7 +1022,6 @@ class Client:
|
||||||
async def get_sym_details(
|
async def get_sym_details(
|
||||||
self,
|
self,
|
||||||
fqme: str,
|
fqme: str,
|
||||||
|
|
||||||
) -> tuple[
|
) -> tuple[
|
||||||
Contract,
|
Contract,
|
||||||
ContractDetails,
|
ContractDetails,
|
||||||
|
|
@ -1092,7 +1121,7 @@ class Client:
|
||||||
size: int,
|
size: int,
|
||||||
account: str, # if blank the "default" tws account is used
|
account: str, # if blank the "default" tws account is used
|
||||||
|
|
||||||
# XXX: by default 0 tells ``ib_insync`` methods that there is no
|
# XXX: by default 0 tells ``ib_async`` methods that there is no
|
||||||
# existing order so ask the client to create a new one (which it
|
# existing order so ask the client to create a new one (which it
|
||||||
# seems to do by allocating an int counter - collision prone..)
|
# seems to do by allocating an int counter - collision prone..)
|
||||||
reqid: int = None,
|
reqid: int = None,
|
||||||
|
|
@ -1281,7 +1310,7 @@ async def load_aio_clients(
|
||||||
port: int = None,
|
port: int = None,
|
||||||
client_id: int = 6116,
|
client_id: int = 6116,
|
||||||
|
|
||||||
# the API TCP in `ib_insync` connection can be flaky af so instead
|
# the API TCP in `ib_async` connection can be flaky af so instead
|
||||||
# retry a few times to get the client going..
|
# retry a few times to get the client going..
|
||||||
connect_retries: int = 3,
|
connect_retries: int = 3,
|
||||||
connect_timeout: float = 30, # in case a remote-host
|
connect_timeout: float = 30, # in case a remote-host
|
||||||
|
|
@ -1289,7 +1318,7 @@ async def load_aio_clients(
|
||||||
|
|
||||||
) -> dict[str, Client]:
|
) -> dict[str, Client]:
|
||||||
'''
|
'''
|
||||||
Return an ``ib_insync.IB`` instance wrapped in our client API.
|
Return an ``ib_async.IB`` instance wrapped in our client API.
|
||||||
|
|
||||||
Client instances are cached for later use.
|
Client instances are cached for later use.
|
||||||
|
|
||||||
|
|
@ -1631,6 +1660,7 @@ async def open_aio_client_method_relay(
|
||||||
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
|
# with tractor.devx.maybe_open_crash_handler() as _bxerr:
|
||||||
# sync with `open_client_proxy()` caller
|
# sync with `open_client_proxy()` caller
|
||||||
chan.started_nowait(client)
|
chan.started_nowait(client)
|
||||||
|
|
||||||
|
|
@ -1640,7 +1670,11 @@ async def open_aio_client_method_relay(
|
||||||
# relay all method requests to ``asyncio``-side client and deliver
|
# relay all method requests to ``asyncio``-side client and deliver
|
||||||
# back results
|
# back results
|
||||||
while not chan._to_trio._closed: # <- TODO, better check like `._web_bs`?
|
while not chan._to_trio._closed: # <- TODO, better check like `._web_bs`?
|
||||||
msg: tuple[str, dict]|dict|None = await chan.get()
|
msg: (
|
||||||
|
None
|
||||||
|
|tuple[str, dict]
|
||||||
|
|dict
|
||||||
|
) = await chan.get()
|
||||||
match msg:
|
match msg:
|
||||||
case None: # termination sentinel
|
case None: # termination sentinel
|
||||||
log.info('asyncio `Client` method-proxy SHUTDOWN!')
|
log.info('asyncio `Client` method-proxy SHUTDOWN!')
|
||||||
|
|
@ -1742,7 +1776,7 @@ async def get_client(
|
||||||
|
|
||||||
) -> Client:
|
) -> Client:
|
||||||
'''
|
'''
|
||||||
Init the ``ib_insync`` client in another actor and return
|
Init the ``ib_async`` client in another actor and return
|
||||||
a method proxy to it.
|
a method proxy to it.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,14 @@ from trio_typing import TaskStatus
|
||||||
import tractor
|
import tractor
|
||||||
from tractor.to_asyncio import LinkedTaskChannel
|
from tractor.to_asyncio import LinkedTaskChannel
|
||||||
from tractor import trionics
|
from tractor import trionics
|
||||||
from ib_insync.contract import (
|
from ib_async.contract import (
|
||||||
Contract,
|
Contract,
|
||||||
)
|
)
|
||||||
from ib_insync.order import (
|
from ib_async.order import (
|
||||||
Trade,
|
Trade,
|
||||||
OrderStatus,
|
OrderStatus,
|
||||||
)
|
)
|
||||||
from ib_insync.objects import (
|
from ib_async.objects import (
|
||||||
Fill,
|
Fill,
|
||||||
Execution,
|
Execution,
|
||||||
CommissionReport,
|
CommissionReport,
|
||||||
|
|
@ -181,7 +181,7 @@ async def handle_order_requests(
|
||||||
# validate
|
# validate
|
||||||
order = BrokerdOrder(**request_msg)
|
order = BrokerdOrder(**request_msg)
|
||||||
|
|
||||||
# XXX: by default 0 tells ``ib_insync`` methods that
|
# XXX: by default 0 tells ``ib_async`` methods that
|
||||||
# there is no existing order so ask the client to create
|
# there is no existing order so ask the client to create
|
||||||
# a new one (which it seems to do by allocating an int
|
# a new one (which it seems to do by allocating an int
|
||||||
# counter - collision prone..)
|
# counter - collision prone..)
|
||||||
|
|
@ -237,7 +237,7 @@ async def recv_trade_updates(
|
||||||
) -> None:
|
) -> None:
|
||||||
'''
|
'''
|
||||||
Receive and relay order control and positioning related events
|
Receive and relay order control and positioning related events
|
||||||
from `ib_insync`, pack as tuples and push over mem-chan to our
|
from `ib_async`, pack as tuples and push over mem-chan to our
|
||||||
trio relay task for processing and relay to EMS.
|
trio relay task for processing and relay to EMS.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
@ -303,7 +303,7 @@ async def recv_trade_updates(
|
||||||
# much more then a few more pnl fields..
|
# much more then a few more pnl fields..
|
||||||
# 'updatePortfolioEvent',
|
# 'updatePortfolioEvent',
|
||||||
|
|
||||||
# XXX: these all seem to be weird ib_insync internal
|
# XXX: these all seem to be weird ib_async internal
|
||||||
# events that we probably don't care that much about
|
# events that we probably don't care that much about
|
||||||
# given the internal design is wonky af..
|
# given the internal design is wonky af..
|
||||||
# 'newOrderEvent',
|
# 'newOrderEvent',
|
||||||
|
|
@ -499,7 +499,7 @@ async def open_trade_event_stream(
|
||||||
] = trio.TASK_STATUS_IGNORED,
|
] = trio.TASK_STATUS_IGNORED,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Proxy wrapper for starting trade event stream from ib_insync
|
Proxy wrapper for starting trade event stream from ib_async
|
||||||
which spawns an asyncio task that registers an internal closure
|
which spawns an asyncio task that registers an internal closure
|
||||||
(`push_tradies()`) which in turn relays trading events through
|
(`push_tradies()`) which in turn relays trading events through
|
||||||
a `tractor.to_asyncio.LinkedTaskChannel` which the parent
|
a `tractor.to_asyncio.LinkedTaskChannel` which the parent
|
||||||
|
|
@ -991,6 +991,9 @@ _statuses: dict[str, str] = {
|
||||||
# TODO: see a current ``ib_insync`` issue around this:
|
# TODO: see a current ``ib_insync`` issue around this:
|
||||||
# https://github.com/erdewit/ib_insync/issues/363
|
# https://github.com/erdewit/ib_insync/issues/363
|
||||||
'Inactive': 'pending',
|
'Inactive': 'pending',
|
||||||
|
|
||||||
|
# XXX, uhh wut the heck is this?
|
||||||
|
'ValidationError': 'error',
|
||||||
}
|
}
|
||||||
|
|
||||||
_action_map = {
|
_action_map = {
|
||||||
|
|
@ -1063,8 +1066,19 @@ async def deliver_trade_events(
|
||||||
# TODO: for some reason we can receive a ``None`` here when the
|
# TODO: for some reason we can receive a ``None`` here when the
|
||||||
# ib-gw goes down? Not sure exactly how that's happening looking
|
# ib-gw goes down? Not sure exactly how that's happening looking
|
||||||
# at the eventkit code above but we should probably handle it...
|
# at the eventkit code above but we should probably handle it...
|
||||||
|
event_name: str
|
||||||
|
item: (
|
||||||
|
Trade
|
||||||
|
|tuple[Trade, Fill]
|
||||||
|
|CommissionReport
|
||||||
|
|IbPosition
|
||||||
|
|dict
|
||||||
|
)
|
||||||
async for event_name, item in trade_event_stream:
|
async for event_name, item in trade_event_stream:
|
||||||
log.info(f'Relaying `{event_name}`:\n{pformat(item)}')
|
log.info(
|
||||||
|
f'Relaying {event_name!r}:\n'
|
||||||
|
f'{pformat(item)}\n'
|
||||||
|
)
|
||||||
match event_name:
|
match event_name:
|
||||||
case 'orderStatusEvent':
|
case 'orderStatusEvent':
|
||||||
|
|
||||||
|
|
@ -1075,11 +1089,12 @@ async def deliver_trade_events(
|
||||||
trade: Trade = item
|
trade: Trade = item
|
||||||
reqid: str = str(trade.order.orderId)
|
reqid: str = str(trade.order.orderId)
|
||||||
status: OrderStatus = trade.orderStatus
|
status: OrderStatus = trade.orderStatus
|
||||||
status_str: str = _statuses[status.status]
|
status_str: str = _statuses.get(
|
||||||
|
status.status,
|
||||||
|
'error',
|
||||||
|
)
|
||||||
remaining: float = status.remaining
|
remaining: float = status.remaining
|
||||||
if (
|
if status_str == 'filled':
|
||||||
status_str == 'filled'
|
|
||||||
):
|
|
||||||
fill: Fill = trade.fills[-1]
|
fill: Fill = trade.fills[-1]
|
||||||
execu: Execution = fill.execution
|
execu: Execution = fill.execution
|
||||||
|
|
||||||
|
|
@ -1110,6 +1125,12 @@ async def deliver_trade_events(
|
||||||
# all units were cleared.
|
# all units were cleared.
|
||||||
status_str = 'closed'
|
status_str = 'closed'
|
||||||
|
|
||||||
|
elif status_str == 'error':
|
||||||
|
log.error(
|
||||||
|
f'IB reported error status for order ??\n'
|
||||||
|
f'{status.status!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
# skip duplicate filled updates - we get the deats
|
# skip duplicate filled updates - we get the deats
|
||||||
# from the execution details event
|
# from the execution details event
|
||||||
msg = BrokerdStatus(
|
msg = BrokerdStatus(
|
||||||
|
|
@ -1270,14 +1291,24 @@ async def deliver_trade_events(
|
||||||
case 'error':
|
case 'error':
|
||||||
# NOTE: see impl deats in
|
# NOTE: see impl deats in
|
||||||
# `Client.inline_errors()::push_err()`
|
# `Client.inline_errors()::push_err()`
|
||||||
err: dict = item
|
err: dict|str = item
|
||||||
|
|
||||||
# never relay errors for non-broker related issues
|
# std case, never relay errors for non-order-control
|
||||||
|
# related issues.
|
||||||
# https://interactivebrokers.github.io/tws-api/message_codes.html
|
# https://interactivebrokers.github.io/tws-api/message_codes.html
|
||||||
|
if isinstance(err, dict):
|
||||||
code: int = err['error_code']
|
code: int = err['error_code']
|
||||||
reason: str = err['reason']
|
reason: str = err['reason']
|
||||||
reqid: str = str(err['reqid'])
|
reqid: str = str(err['reqid'])
|
||||||
|
|
||||||
|
# XXX, sometimes you'll get just a `str` of the form,
|
||||||
|
# '[code 104] connection failed' or something..
|
||||||
|
elif isinstance(err, str):
|
||||||
|
code_part, _, reason = err.rpartition(']')
|
||||||
|
if code_part:
|
||||||
|
_, _, code = code_part.partition('[code')
|
||||||
|
reqid: str = '<unknown>'
|
||||||
|
|
||||||
# "Warning:" msg codes,
|
# "Warning:" msg codes,
|
||||||
# https://interactivebrokers.github.io/tws-api/message_codes.html#warning_codes
|
# https://interactivebrokers.github.io/tws-api/message_codes.html#warning_codes
|
||||||
# - 2109: 'Outside Regular Trading Hours'
|
# - 2109: 'Outside Regular Trading Hours'
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ from typing import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from async_generator import aclosing
|
from async_generator import aclosing
|
||||||
import ib_insync as ibis
|
import ib_async as ibis
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from pendulum import (
|
from pendulum import (
|
||||||
now,
|
now,
|
||||||
|
|
@ -100,7 +100,7 @@ tick_types = {
|
||||||
5: 'size',
|
5: 'size',
|
||||||
8: 'volume',
|
8: 'volume',
|
||||||
|
|
||||||
# ``ib_insync`` already packs these into
|
# `ib_async` already packs these into
|
||||||
# quotes under the following fields.
|
# quotes under the following fields.
|
||||||
55: 'trades_per_min', # `'tradeRate'`
|
55: 'trades_per_min', # `'tradeRate'`
|
||||||
56: 'vlm_per_min', # `'volumeRate'`
|
56: 'vlm_per_min', # `'volumeRate'`
|
||||||
|
|
@ -201,6 +201,15 @@ async def open_history_client(
|
||||||
fqme,
|
fqme,
|
||||||
timeframe,
|
timeframe,
|
||||||
end_dt=end_dt,
|
end_dt=end_dt,
|
||||||
|
|
||||||
|
# XXX WARNING, we don't actually use this inside
|
||||||
|
# `Client.bars()` since it isn't really supported,
|
||||||
|
# the API instead supports a "duration" of time style
|
||||||
|
# from the `end_dt` (or at least that was the best
|
||||||
|
# way to get it working sanely)..
|
||||||
|
#
|
||||||
|
# SO, with that in mind be aware that any downstream
|
||||||
|
# logic based on this may be mostly futile Xp
|
||||||
start_dt=start_dt,
|
start_dt=start_dt,
|
||||||
)
|
)
|
||||||
latency = time.time() - query_start
|
latency = time.time() - query_start
|
||||||
|
|
@ -278,19 +287,27 @@ async def open_history_client(
|
||||||
trimmed_bars = bars_array[
|
trimmed_bars = bars_array[
|
||||||
bars_array['time'] >= start_dt.timestamp()
|
bars_array['time'] >= start_dt.timestamp()
|
||||||
]
|
]
|
||||||
|
# XXX, should NEVER get HERE!
|
||||||
|
if trimmed_bars.size:
|
||||||
|
trimmed_first_dt: datetime = from_timestamp(trimmed_bars['time'][0])
|
||||||
if (
|
if (
|
||||||
trimmed_first_dt := from_timestamp(trimmed_bars['time'][0])
|
trimmed_first_dt
|
||||||
!=
|
>=
|
||||||
start_dt
|
start_dt
|
||||||
):
|
):
|
||||||
# TODO! rm this once we're more confident it never hits!
|
msg: str = (
|
||||||
# breakpoint()
|
|
||||||
raise RuntimeError(
|
|
||||||
f'OHLC-bars array start is gt `start_dt` limit !!\n'
|
f'OHLC-bars array start is gt `start_dt` limit !!\n'
|
||||||
f'start_dt: {start_dt}\n'
|
f'start_dt: {start_dt}\n'
|
||||||
f'first_dt: {first_dt}\n'
|
f'first_dt: {first_dt}\n'
|
||||||
f'trimmed_first_dt: {trimmed_first_dt}\n'
|
f'trimmed_first_dt: {trimmed_first_dt}\n'
|
||||||
|
f'\n'
|
||||||
|
f'Delivering shorted frame of {trimmed_bars.size!r}\n'
|
||||||
)
|
)
|
||||||
|
log.warning(msg)
|
||||||
|
# TODO! rm this once we're more confident it
|
||||||
|
# never breaks anything (in the caller)!
|
||||||
|
# breakpoint()
|
||||||
|
# raise RuntimeError(msg)
|
||||||
|
|
||||||
# XXX, overwrite with start_dt-limited frame
|
# XXX, overwrite with start_dt-limited frame
|
||||||
bars_array = trimmed_bars
|
bars_array = trimmed_bars
|
||||||
|
|
@ -304,7 +321,7 @@ async def open_history_client(
|
||||||
# TODO: it seems like we can do async queries for ohlc
|
# TODO: it seems like we can do async queries for ohlc
|
||||||
# but getting the order right still isn't working and I'm not
|
# but getting the order right still isn't working and I'm not
|
||||||
# quite sure why.. needs some tinkering and probably
|
# quite sure why.. needs some tinkering and probably
|
||||||
# a lookthrough of the `ib_insync` machinery, for eg. maybe
|
# a lookthrough of the `ib_async` machinery, for eg. maybe
|
||||||
# we have to do the batch queries on the `asyncio` side?
|
# we have to do the batch queries on the `asyncio` side?
|
||||||
yield (
|
yield (
|
||||||
get_hist,
|
get_hist,
|
||||||
|
|
@ -1051,6 +1068,21 @@ def normalize(
|
||||||
# ticker.rtTime.timestamp) / 1000.
|
# ticker.rtTime.timestamp) / 1000.
|
||||||
data.pop('rtTime')
|
data.pop('rtTime')
|
||||||
|
|
||||||
|
# XXX, `ib_async` seems to set a
|
||||||
|
# `'timezone': datetime.timezone.utc` in this `dict`
|
||||||
|
# which is NOT IPC serializeable sin codec!
|
||||||
|
#
|
||||||
|
# pretty sure we don't need any of this field for now anyway?
|
||||||
|
data.pop('defaults')
|
||||||
|
|
||||||
|
if lts := data.get('lastTimeStamp'):
|
||||||
|
lts.replace(tzinfo=None)
|
||||||
|
log.warning(
|
||||||
|
f'Stripping `.tzinfo` from datetime\n'
|
||||||
|
f'{lts}\n'
|
||||||
|
)
|
||||||
|
# breakpoint()
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1227,7 +1259,7 @@ async def stream_quotes(
|
||||||
):
|
):
|
||||||
# ?TODO? can we rm this - particularly for `ib_async`?
|
# ?TODO? can we rm this - particularly for `ib_async`?
|
||||||
# ugh, clear ticks since we've consumed them
|
# ugh, clear ticks since we've consumed them
|
||||||
# (ahem, ib_insync is stateful trash)
|
# (ahem, ib_async is stateful trash)
|
||||||
# first_ticker.ticks = []
|
# first_ticker.ticks = []
|
||||||
|
|
||||||
# only on first entry at feed boot up
|
# only on first entry at feed boot up
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ from pendulum import (
|
||||||
parse,
|
parse,
|
||||||
from_timestamp,
|
from_timestamp,
|
||||||
)
|
)
|
||||||
from ib_insync import (
|
from ib_async import (
|
||||||
Contract,
|
Contract,
|
||||||
Commodity,
|
Commodity,
|
||||||
Fill,
|
Fill,
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ from contextlib import (
|
||||||
nullcontext,
|
nullcontext,
|
||||||
)
|
)
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from functools import partial
|
||||||
import time
|
import time
|
||||||
from typing import (
|
from typing import (
|
||||||
Awaitable,
|
Awaitable,
|
||||||
|
|
@ -30,8 +31,9 @@ from typing import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from rapidfuzz import process as fuzzy
|
from rapidfuzz import process as fuzzy
|
||||||
import ib_insync as ibis
|
import ib_async as ibis
|
||||||
import tractor
|
import tractor
|
||||||
|
from tractor.devx.pformat import ppfmt
|
||||||
import trio
|
import trio
|
||||||
|
|
||||||
from piker.accounting import (
|
from piker.accounting import (
|
||||||
|
|
@ -215,18 +217,19 @@ async def open_symbol_search(ctx: tractor.Context) -> None:
|
||||||
f'{ib_client}\n'
|
f'{ib_client}\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
last = time.time()
|
last: float = time.time()
|
||||||
async for pattern in stream:
|
async for pattern in stream:
|
||||||
log.info(f'received {pattern}')
|
log.info(f'received {pattern}')
|
||||||
now: float = time.time()
|
now: float = time.time()
|
||||||
|
|
||||||
|
# TODO? check this is no longer true?
|
||||||
# this causes tractor hang...
|
# this causes tractor hang...
|
||||||
# assert 0
|
# assert 0
|
||||||
|
|
||||||
assert pattern, 'IB can not accept blank search pattern'
|
assert pattern, 'IB can not accept blank search pattern'
|
||||||
|
|
||||||
# throttle search requests to no faster then 1Hz
|
# throttle search requests to no faster then 1Hz
|
||||||
diff = now - last
|
diff: float = now - last
|
||||||
if diff < 1.0:
|
if diff < 1.0:
|
||||||
log.debug('throttle sleeping')
|
log.debug('throttle sleeping')
|
||||||
await trio.sleep(diff)
|
await trio.sleep(diff)
|
||||||
|
|
@ -237,11 +240,12 @@ async def open_symbol_search(ctx: tractor.Context) -> None:
|
||||||
|
|
||||||
if (
|
if (
|
||||||
not pattern
|
not pattern
|
||||||
or pattern.isspace()
|
or
|
||||||
|
pattern.isspace()
|
||||||
|
or
|
||||||
# XXX: not sure if this is a bad assumption but it
|
# XXX: not sure if this is a bad assumption but it
|
||||||
# seems to make search snappier?
|
# seems to make search snappier?
|
||||||
or len(pattern) < 1
|
len(pattern) < 1
|
||||||
):
|
):
|
||||||
log.warning('empty pattern received, skipping..')
|
log.warning('empty pattern received, skipping..')
|
||||||
|
|
||||||
|
|
@ -254,36 +258,58 @@ async def open_symbol_search(ctx: tractor.Context) -> None:
|
||||||
# XXX: this unblocks the far end search task which may
|
# XXX: this unblocks the far end search task which may
|
||||||
# hold up a multi-search nursery block
|
# hold up a multi-search nursery block
|
||||||
await stream.send({})
|
await stream.send({})
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
log.info(f'searching for {pattern}')
|
log.info(
|
||||||
|
f'Searching for FQME with,\n'
|
||||||
|
f'pattern: {pattern!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
last = time.time()
|
last: float = time.time()
|
||||||
|
|
||||||
# async batch search using api stocks endpoint and module
|
# async batch search using api stocks endpoint and
|
||||||
# defined adhoc symbol set.
|
# module defined adhoc symbol set.
|
||||||
stock_results = []
|
stock_results: list[dict] = []
|
||||||
|
|
||||||
async def extend_results(
|
async def extend_results(
|
||||||
target: Awaitable[list]
|
# ?TODO, how to type async-fn!?
|
||||||
|
target: Awaitable[list],
|
||||||
|
pattern: str,
|
||||||
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
try:
|
try:
|
||||||
results = await target
|
results = await target(
|
||||||
|
pattern=pattern,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
client_repr: str = proxy._aio_ns.ib.client.__class__.__name__
|
||||||
|
meth_repr: str = target.keywords["meth"]
|
||||||
|
log.info(
|
||||||
|
f'Search query,\n'
|
||||||
|
f'{client_repr}.{meth_repr}(\n'
|
||||||
|
f' pattern={pattern!r}\n'
|
||||||
|
f' **kwargs={kwargs!r},\n'
|
||||||
|
f') = {ppfmt(list(results))}'
|
||||||
|
# XXX ^ just the keys since that's what
|
||||||
|
# shows in UI results table.
|
||||||
|
)
|
||||||
except tractor.trionics.Lagged:
|
except tractor.trionics.Lagged:
|
||||||
print("IB SYM-SEARCH OVERRUN?!?")
|
log.exception(
|
||||||
|
'IB SYM-SEARCH OVERRUN?!?\n'
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
stock_results.extend(results)
|
stock_results.extend(results)
|
||||||
|
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
with trio.move_on_after(3) as cs:
|
with trio.move_on_after(3) as cs:
|
||||||
async with trio.open_nursery() as sn:
|
async with trio.open_nursery() as tn:
|
||||||
sn.start_soon(
|
tn.start_soon(
|
||||||
|
partial(
|
||||||
extend_results,
|
extend_results,
|
||||||
proxy.search_symbols(
|
|
||||||
pattern=pattern,
|
pattern=pattern,
|
||||||
upto=5,
|
target=proxy.search_symbols,
|
||||||
|
upto=10,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -313,7 +339,9 @@ async def open_symbol_search(ctx: tractor.Context) -> None:
|
||||||
# adhoc_match_results = {i[0]: {} for i in
|
# adhoc_match_results = {i[0]: {} for i in
|
||||||
# adhoc_matches}
|
# adhoc_matches}
|
||||||
|
|
||||||
log.debug(f'fuzzy matching stocks {stock_results}')
|
log.debug(
|
||||||
|
f'fuzzy matching stocks {ppfmt(stock_results)}'
|
||||||
|
)
|
||||||
stock_matches = fuzzy.extract(
|
stock_matches = fuzzy.extract(
|
||||||
pattern,
|
pattern,
|
||||||
stock_results,
|
stock_results,
|
||||||
|
|
@ -327,7 +355,10 @@ async def open_symbol_search(ctx: tractor.Context) -> None:
|
||||||
# TODO: we used to deliver contract details
|
# TODO: we used to deliver contract details
|
||||||
# {item[2]: item[0] for item in stock_matches}
|
# {item[2]: item[0] for item in stock_matches}
|
||||||
|
|
||||||
log.debug(f"sending matches: {matches.keys()}")
|
log.debug(
|
||||||
|
f'Sending final matches\n'
|
||||||
|
f'{matches.keys()}'
|
||||||
|
)
|
||||||
await stream.send(matches)
|
await stream.send(matches)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -522,7 +553,11 @@ async def get_mkt_info(
|
||||||
if atype == 'commodity':
|
if atype == 'commodity':
|
||||||
venue: str = 'cmdty'
|
venue: str = 'cmdty'
|
||||||
else:
|
else:
|
||||||
venue = con.primaryExchange or con.exchange
|
venue: str = (
|
||||||
|
con.primaryExchange
|
||||||
|
or
|
||||||
|
con.exchange
|
||||||
|
)
|
||||||
|
|
||||||
price_tick: Decimal = Decimal(str(details.minTick))
|
price_tick: Decimal = Decimal(str(details.minTick))
|
||||||
ib_min_tick_gt_2: Decimal = Decimal('0.01')
|
ib_min_tick_gt_2: Decimal = Decimal('0.01')
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,9 @@ from pendulum import (
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ib_insync import (
|
from ib_async import (
|
||||||
TradingSession,
|
TradingSession,
|
||||||
|
Contract,
|
||||||
ContractDetails,
|
ContractDetails,
|
||||||
)
|
)
|
||||||
from exchange_calendars.exchange_calendars import (
|
from exchange_calendars.exchange_calendars import (
|
||||||
|
|
@ -82,8 +83,20 @@ def has_holiday(
|
||||||
|
|
||||||
'''
|
'''
|
||||||
tz: str = con_deats.timeZoneId
|
tz: str = con_deats.timeZoneId
|
||||||
exch: str = con_deats.contract.primaryExchange
|
con: Contract = con_deats.contract
|
||||||
cal: ExchangeCalendar = xcals.get_calendar(exch)
|
exch: str = (
|
||||||
|
con.primaryExchange
|
||||||
|
or
|
||||||
|
con.exchange
|
||||||
|
)
|
||||||
|
|
||||||
|
# XXX, ad-hoc handle any IB exchange which are non-std
|
||||||
|
# via lookup table..
|
||||||
|
std_exch: dict = {
|
||||||
|
'ARCA': 'ARCX',
|
||||||
|
}.get(exch, exch)
|
||||||
|
|
||||||
|
cal: ExchangeCalendar = xcals.get_calendar(std_exch)
|
||||||
end: datetime = period.end
|
end: datetime = period.end
|
||||||
# _start: datetime = period.start
|
# _start: datetime = period.start
|
||||||
# ?TODO, can rm ya?
|
# ?TODO, can rm ya?
|
||||||
|
|
@ -236,7 +249,7 @@ def is_venue_closure(
|
||||||
#
|
#
|
||||||
# NOTE, this was generated by @guille from a gpt5 prompt
|
# NOTE, this was generated by @guille from a gpt5 prompt
|
||||||
# and was originally thot to be needed before learning about
|
# and was originally thot to be needed before learning about
|
||||||
# `ib_insync.contract.ContractDetails._parseSessions()` and
|
# `ib_async.contract.ContractDetails._parseSessions()` and
|
||||||
# it's downstream meths..
|
# it's downstream meths..
|
||||||
#
|
#
|
||||||
# This is still likely useful to keep for now to parse the
|
# This is still likely useful to keep for now to parse the
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ Platform configuration (files) mgmt.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import platform
|
import platform
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from typing import (
|
from typing import (
|
||||||
|
|
@ -29,6 +28,7 @@ from typing import (
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from bidict import bidict
|
from bidict import bidict
|
||||||
|
import platformdirs
|
||||||
import tomlkit
|
import tomlkit
|
||||||
try:
|
try:
|
||||||
import tomllib
|
import tomllib
|
||||||
|
|
@ -41,7 +41,7 @@ from .log import get_logger
|
||||||
log = get_logger('broker-config')
|
log = get_logger('broker-config')
|
||||||
|
|
||||||
|
|
||||||
# XXX NOTE: taken from `click`
|
# XXX NOTE: orig impl was taken from `click`
|
||||||
# |_https://github.com/pallets/click/blob/main/src/click/utils.py#L449
|
# |_https://github.com/pallets/click/blob/main/src/click/utils.py#L449
|
||||||
#
|
#
|
||||||
# (since apparently they have some super weirdness with SIGINT and
|
# (since apparently they have some super weirdness with SIGINT and
|
||||||
|
|
@ -54,44 +54,21 @@ def get_app_dir(
|
||||||
force_posix: bool = False,
|
force_posix: bool = False,
|
||||||
|
|
||||||
) -> str:
|
) -> str:
|
||||||
r"""Returns the config folder for the application. The default behavior
|
'''
|
||||||
|
Returns the config folder for the application. The default behavior
|
||||||
is to return whatever is most appropriate for the operating system.
|
is to return whatever is most appropriate for the operating system.
|
||||||
|
|
||||||
To give you an idea, for an app called ``"Foo Bar"``, something like
|
----
|
||||||
the following folders could be returned:
|
NOTE, below is originally from `click` impl fn, we can prolly remove?
|
||||||
|
----
|
||||||
|
|
||||||
Mac OS X:
|
|
||||||
``~/Library/Application Support/Foo Bar``
|
|
||||||
Mac OS X (POSIX):
|
|
||||||
``~/.foo-bar``
|
|
||||||
Unix:
|
|
||||||
``~/.config/foo-bar``
|
|
||||||
Unix (POSIX):
|
|
||||||
``~/.foo-bar``
|
|
||||||
Win XP (roaming):
|
|
||||||
``C:\Documents and Settings\<user>\Local Settings\Application Data\Foo``
|
|
||||||
Win XP (not roaming):
|
|
||||||
``C:\Documents and Settings\<user>\Application Data\Foo Bar``
|
|
||||||
Win 7 (roaming):
|
|
||||||
``C:\Users\<user>\AppData\Roaming\Foo Bar``
|
|
||||||
Win 7 (not roaming):
|
|
||||||
``C:\Users\<user>\AppData\Local\Foo Bar``
|
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
|
||||||
|
|
||||||
:param app_name: the application name. This should be properly capitalized
|
|
||||||
and can contain whitespace.
|
|
||||||
:param roaming: controls if the folder should be roaming or not on Windows.
|
:param roaming: controls if the folder should be roaming or not on Windows.
|
||||||
Has no affect otherwise.
|
Has no affect otherwise.
|
||||||
:param force_posix: if this is set to `True` then on any POSIX system the
|
:param force_posix: if this is set to `True` then on any POSIX system the
|
||||||
folder will be stored in the home folder with a leading
|
folder will be stored in the home folder with a leading
|
||||||
dot instead of the XDG config home or darwin's
|
dot instead of the XDG config home or darwin's
|
||||||
application support folder.
|
application support folder.
|
||||||
"""
|
'''
|
||||||
|
|
||||||
def _posixify(name):
|
|
||||||
return "-".join(name.split()).lower()
|
|
||||||
|
|
||||||
# NOTE: for testing with `pytest` we leverage the `tmp_dir`
|
# NOTE: for testing with `pytest` we leverage the `tmp_dir`
|
||||||
# fixture to generate (and clean up) a test-request-specific
|
# fixture to generate (and clean up) a test-request-specific
|
||||||
# directory for isolated configuration files such that,
|
# directory for isolated configuration files such that,
|
||||||
|
|
@ -117,23 +94,30 @@ def get_app_dir(
|
||||||
# assert testdirpath.exists(), 'piker test harness might be borked!?'
|
# assert testdirpath.exists(), 'piker test harness might be borked!?'
|
||||||
# app_name = str(testdirpath)
|
# app_name = str(testdirpath)
|
||||||
|
|
||||||
if platform.system() == 'Windows':
|
os_name: str = platform.system()
|
||||||
key = "APPDATA" if roaming else "LOCALAPPDATA"
|
conf_dir: Path = platformdirs.user_config_path()
|
||||||
folder = os.environ.get(key)
|
app_dir: Path = conf_dir / app_name
|
||||||
if folder is None:
|
|
||||||
folder = os.path.expanduser("~")
|
# ?TODO, from `click`; can remove?
|
||||||
return os.path.join(folder, app_name)
|
|
||||||
if force_posix:
|
if force_posix:
|
||||||
|
def _posixify(name):
|
||||||
|
return "-".join(name.split()).lower()
|
||||||
|
|
||||||
return os.path.join(
|
return os.path.join(
|
||||||
os.path.expanduser("~/.{}".format(_posixify(app_name))))
|
os.path.expanduser(
|
||||||
if sys.platform == "darwin":
|
"~/.{}".format(
|
||||||
return os.path.join(
|
_posixify(app_name)
|
||||||
os.path.expanduser("~/Library/Application Support"), app_name
|
|
||||||
)
|
)
|
||||||
return os.path.join(
|
|
||||||
os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")),
|
|
||||||
_posixify(app_name),
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
f'Using user config directory,\n'
|
||||||
|
f'platform.system(): {os_name!r}\n'
|
||||||
|
f'conf_dir: {conf_dir!r}\n'
|
||||||
|
f'app_dir: {conf_dir!r}\n'
|
||||||
|
)
|
||||||
|
return app_dir
|
||||||
|
|
||||||
|
|
||||||
_click_config_dir: Path = Path(get_app_dir('piker'))
|
_click_config_dir: Path = Path(get_app_dir('piker'))
|
||||||
|
|
@ -250,7 +234,9 @@ def repodir() -> Path:
|
||||||
repodir: Path = Path(os.environ.get('GITHUB_WORKSPACE'))
|
repodir: Path = Path(os.environ.get('GITHUB_WORKSPACE'))
|
||||||
confdir: Path = repodir / 'config'
|
confdir: Path = repodir / 'config'
|
||||||
|
|
||||||
assert confdir.is_dir(), f'{confdir} DNE, {repodir} is likely incorrect!'
|
assert confdir.is_dir(), (
|
||||||
|
f'{confdir} DNE, {repodir} is likely incorrect!'
|
||||||
|
)
|
||||||
return repodir
|
return repodir
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -973,9 +973,6 @@ async def open_feed(
|
||||||
# assert flume.mkt.fqme == fqme
|
# assert flume.mkt.fqme == fqme
|
||||||
feed.flumes[fqme] = flume
|
feed.flumes[fqme] = flume
|
||||||
|
|
||||||
# TODO: do we need this?
|
|
||||||
flume.feed = feed
|
|
||||||
|
|
||||||
# attach and cache shm handles
|
# attach and cache shm handles
|
||||||
rt_shm = flume.rt_shm
|
rt_shm = flume.rt_shm
|
||||||
assert rt_shm
|
assert rt_shm
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,6 @@ real-time data processing data-structures.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import (
|
|
||||||
TYPE_CHECKING,
|
|
||||||
)
|
|
||||||
|
|
||||||
import tractor
|
import tractor
|
||||||
import pendulum
|
import pendulum
|
||||||
|
|
@ -38,9 +35,6 @@ from ._sharedmem import (
|
||||||
)
|
)
|
||||||
from piker.accounting import MktPair
|
from piker.accounting import MktPair
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from piker.data.feed import Feed
|
|
||||||
|
|
||||||
|
|
||||||
class Flume(Struct):
|
class Flume(Struct):
|
||||||
'''
|
'''
|
||||||
|
|
@ -80,10 +74,6 @@ class Flume(Struct):
|
||||||
izero_rt: int = 0
|
izero_rt: int = 0
|
||||||
throttle_rate: int | None = None
|
throttle_rate: int | None = None
|
||||||
|
|
||||||
# TODO: do we need this really if we can pull the `Portal` from
|
|
||||||
# ``tractor``'s internals?
|
|
||||||
feed: Feed|None = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rt_shm(self) -> ShmArray:
|
def rt_shm(self) -> ShmArray:
|
||||||
|
|
||||||
|
|
@ -156,7 +146,6 @@ class Flume(Struct):
|
||||||
# will get instead some kind of msg-compat version
|
# will get instead some kind of msg-compat version
|
||||||
# that it can load.
|
# that it can load.
|
||||||
msg.pop('stream')
|
msg.pop('stream')
|
||||||
msg.pop('feed')
|
|
||||||
msg.pop('_rt_shm')
|
msg.pop('_rt_shm')
|
||||||
msg.pop('_hist_shm')
|
msg.pop('_hist_shm')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -200,9 +200,13 @@ def maybe_mk_fsp_shm(
|
||||||
)
|
)
|
||||||
|
|
||||||
# (attempt to) uniquely key the fsp shm buffers
|
# (attempt to) uniquely key the fsp shm buffers
|
||||||
|
# Use hash for macOS compatibility (31 char limit)
|
||||||
|
import hashlib
|
||||||
actor_name, uuid = tractor.current_actor().uid
|
actor_name, uuid = tractor.current_actor().uid
|
||||||
uuid_snip: str = uuid[:16]
|
# Create short hash of sym and target name
|
||||||
key: str = f'piker.{actor_name}[{uuid_snip}].{sym}.{target.name}'
|
content = f'{sym}.{target.name}'
|
||||||
|
content_hash = hashlib.md5(content.encode()).hexdigest()[:8]
|
||||||
|
key: str = f'{uuid[:8]}_{content_hash}.fsp'
|
||||||
|
|
||||||
shm, opened = maybe_open_shm_array(
|
shm, opened = maybe_open_shm_array(
|
||||||
key,
|
key,
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,11 @@ def ldshm(
|
||||||
f'Something is wrong with time period for {shm}:\n{times}'
|
f'Something is wrong with time period for {shm}:\n{times}'
|
||||||
)
|
)
|
||||||
period_s: float = float(max(d1, d2, med))
|
period_s: float = float(max(d1, d2, med))
|
||||||
|
log.info(
|
||||||
|
f'Processing shm buffer:\n'
|
||||||
|
f' file: {shmfile.name}\n'
|
||||||
|
f' period: {period_s}s\n'
|
||||||
|
)
|
||||||
|
|
||||||
null_segs: tuple = tsp.get_null_segs(
|
null_segs: tuple = tsp.get_null_segs(
|
||||||
frame=shm.array,
|
frame=shm.array,
|
||||||
|
|
|
||||||
|
|
@ -276,14 +276,41 @@ def get_null_segs(
|
||||||
absi_zdiff: np.ndarray = np.diff(absi_zeros)
|
absi_zdiff: np.ndarray = np.diff(absi_zeros)
|
||||||
|
|
||||||
if zero_t.size < 2:
|
if zero_t.size < 2:
|
||||||
try:
|
idx: int = zero_t['index'][0]
|
||||||
breakpoint()
|
idx_before: int = idx - 1
|
||||||
except RuntimeError:
|
idx_after: int = idx + 1
|
||||||
# XXX, if greenback not active from
|
index = frame['index']
|
||||||
# piker store ldshm cmd..
|
before_cond = idx_before <= index
|
||||||
log.exception(
|
after_cond = index <= idx_after
|
||||||
"Can't debug single-sample null!\n"
|
bars: np.ndarray = frame[
|
||||||
|
before_cond
|
||||||
|
&
|
||||||
|
after_cond
|
||||||
|
]
|
||||||
|
time: np.ndarray = bars['time']
|
||||||
|
from pendulum import (
|
||||||
|
from_timestamp,
|
||||||
|
Interval,
|
||||||
)
|
)
|
||||||
|
gap: Interval = (
|
||||||
|
from_timestamp(time[-1])
|
||||||
|
-
|
||||||
|
from_timestamp(time[0])
|
||||||
|
)
|
||||||
|
log.warning(
|
||||||
|
f'Single OHLCV-bar null-segment detected??\n'
|
||||||
|
f'gap -> {gap}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# ^^XXX, if you want to debug the above bar-gap^^
|
||||||
|
# try:
|
||||||
|
# breakpoint()
|
||||||
|
# except RuntimeError:
|
||||||
|
# # XXX, if greenback not active from
|
||||||
|
# # piker store ldshm cmd..
|
||||||
|
# log.exception(
|
||||||
|
# "Can't debug single-sample null!\n"
|
||||||
|
# )
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ import tractor
|
||||||
|
|
||||||
from piker.data._formatters import BGM
|
from piker.data._formatters import BGM
|
||||||
from piker.storage import log
|
from piker.storage import log
|
||||||
|
from piker.toolz.profile import (
|
||||||
|
Profiler,
|
||||||
|
pg_profile_enabled,
|
||||||
|
ms_slower_then,
|
||||||
|
)
|
||||||
from piker.ui._style import get_fonts
|
from piker.ui._style import get_fonts
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -92,12 +97,22 @@ async def markup_gaps(
|
||||||
# gap's duration.
|
# gap's duration.
|
||||||
show_txt: bool = False,
|
show_txt: bool = False,
|
||||||
|
|
||||||
|
# A/B comparison: render individual arrows alongside batch
|
||||||
|
# for visual comparison
|
||||||
|
show_individual_arrows: bool = False,
|
||||||
|
|
||||||
) -> dict[int, dict]:
|
) -> dict[int, dict]:
|
||||||
'''
|
'''
|
||||||
Remote annotate time-gaps in a dt-fielded ts (normally OHLC)
|
Remote annotate time-gaps in a dt-fielded ts (normally OHLC)
|
||||||
with rectangles.
|
with rectangles.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
profiler = Profiler(
|
||||||
|
msg=f'markup_gaps() for {gaps.height} gaps',
|
||||||
|
disabled=False,
|
||||||
|
ms_threshold=0.0,
|
||||||
|
)
|
||||||
|
|
||||||
# XXX: force chart redraw FIRST to ensure PlotItem coordinate
|
# XXX: force chart redraw FIRST to ensure PlotItem coordinate
|
||||||
# system is properly initialized before we position annotations!
|
# system is properly initialized before we position annotations!
|
||||||
# Without this, annotations may be misaligned on first creation
|
# Without this, annotations may be misaligned on first creation
|
||||||
|
|
@ -106,6 +121,19 @@ async def markup_gaps(
|
||||||
fqme=fqme,
|
fqme=fqme,
|
||||||
timeframe=timeframe,
|
timeframe=timeframe,
|
||||||
)
|
)
|
||||||
|
profiler('first `.redraw()` before annot creation')
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
f'markup_gaps() called:\n'
|
||||||
|
f' fqme: {fqme}\n'
|
||||||
|
f' timeframe: {timeframe}s\n'
|
||||||
|
f' gaps.height: {gaps.height}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# collect all annotation specs for batch submission
|
||||||
|
rect_specs: list[dict] = []
|
||||||
|
arrow_specs: list[dict] = []
|
||||||
|
text_specs: list[dict] = []
|
||||||
|
|
||||||
aids: dict[int] = {}
|
aids: dict[int] = {}
|
||||||
for i in range(gaps.height):
|
for i in range(gaps.height):
|
||||||
|
|
@ -217,56 +245,38 @@ async def markup_gaps(
|
||||||
# 1: 'wine', # down-gap
|
# 1: 'wine', # down-gap
|
||||||
# }[sgn]
|
# }[sgn]
|
||||||
|
|
||||||
rect_kwargs: dict[str, Any] = dict(
|
# collect rect spec (no fqme/timeframe, added by batch
|
||||||
fqme=fqme,
|
# API)
|
||||||
timeframe=timeframe,
|
rect_spec: dict[str, Any] = dict(
|
||||||
|
meth='set_view_pos',
|
||||||
start_pos=lc,
|
start_pos=lc,
|
||||||
end_pos=ro,
|
end_pos=ro,
|
||||||
color=color,
|
color=color,
|
||||||
|
update_label=False,
|
||||||
start_time=start_time,
|
start_time=start_time,
|
||||||
end_time=end_time,
|
end_time=end_time,
|
||||||
)
|
)
|
||||||
|
rect_specs.append(rect_spec)
|
||||||
|
|
||||||
# add up/down rects
|
|
||||||
aid: int|None = await actl.add_rect(**rect_kwargs)
|
|
||||||
if aid is None:
|
|
||||||
log.error(
|
|
||||||
f'Failed to add rect for,\n'
|
|
||||||
f'{rect_kwargs!r}\n'
|
|
||||||
f'\n'
|
|
||||||
f'Skipping to next gap!\n'
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
assert aid
|
|
||||||
aids[aid] = rect_kwargs
|
|
||||||
direction: str = (
|
direction: str = (
|
||||||
'down' if down_gap
|
'down' if down_gap
|
||||||
else 'up'
|
else 'up'
|
||||||
)
|
)
|
||||||
# TODO! mk this a `msgspec.Struct` which we deserialize
|
|
||||||
# on the server side!
|
# collect arrow spec
|
||||||
# XXX: send timestamp for server-side index lookup
|
|
||||||
# to ensure alignment with current shm state
|
|
||||||
gap_time: float = row['time'][0]
|
gap_time: float = row['time'][0]
|
||||||
arrow_kwargs: dict[str, Any] = dict(
|
arrow_spec: dict[str, Any] = dict(
|
||||||
fqme=fqme,
|
|
||||||
timeframe=timeframe,
|
|
||||||
x=iend, # fallback if timestamp lookup fails
|
x=iend, # fallback if timestamp lookup fails
|
||||||
y=cls,
|
y=cls,
|
||||||
time=gap_time, # for server-side index lookup
|
time=gap_time, # for server-side index lookup
|
||||||
color=color,
|
color=color,
|
||||||
alpha=169,
|
alpha=169,
|
||||||
pointing=direction,
|
pointing=direction,
|
||||||
# TODO: expose these as params to markup_gaps()?
|
|
||||||
headLen=10,
|
headLen=10,
|
||||||
headWidth=2.222,
|
headWidth=2.222,
|
||||||
pxMode=True,
|
pxMode=True,
|
||||||
)
|
)
|
||||||
|
arrow_specs.append(arrow_spec)
|
||||||
aid: int = await actl.add_arrow(
|
|
||||||
**arrow_kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
# add duration label to RHS of arrow
|
# add duration label to RHS of arrow
|
||||||
if up_gap:
|
if up_gap:
|
||||||
|
|
@ -278,15 +288,12 @@ async def markup_gaps(
|
||||||
assert flat
|
assert flat
|
||||||
anchor = (0, 0) # up from bottom
|
anchor = (0, 0) # up from bottom
|
||||||
|
|
||||||
# use a slightly smaller font for gap label txt.
|
# collect text spec if enabled
|
||||||
|
if show_txt:
|
||||||
font, small_font = get_fonts()
|
font, small_font = get_fonts()
|
||||||
font_size: int = small_font.px_size - 1
|
font_size: int = small_font.px_size - 1
|
||||||
assert isinstance(font_size, int)
|
|
||||||
|
|
||||||
if show_txt:
|
text_spec: dict[str, Any] = dict(
|
||||||
text_aid: int = await actl.add_text(
|
|
||||||
fqme=fqme,
|
|
||||||
timeframe=timeframe,
|
|
||||||
text=gap_label,
|
text=gap_label,
|
||||||
x=iend + 1, # fallback if timestamp lookup fails
|
x=iend + 1, # fallback if timestamp lookup fails
|
||||||
y=cls,
|
y=cls,
|
||||||
|
|
@ -295,12 +302,46 @@ async def markup_gaps(
|
||||||
anchor=anchor,
|
anchor=anchor,
|
||||||
font_size=font_size,
|
font_size=font_size,
|
||||||
)
|
)
|
||||||
aids[text_aid] = {'text': gap_label}
|
text_specs.append(text_spec)
|
||||||
|
|
||||||
# tell chart to redraw all its
|
# submit all annotations in single batch IPC msg
|
||||||
# graphics view layers Bo
|
log.info(
|
||||||
|
f'Submitting batch annotations:\n'
|
||||||
|
f' rects: {len(rect_specs)}\n'
|
||||||
|
f' arrows: {len(arrow_specs)}\n'
|
||||||
|
f' texts: {len(text_specs)}\n'
|
||||||
|
)
|
||||||
|
profiler('built all annotation specs')
|
||||||
|
|
||||||
|
result: dict[str, list[int]] = await actl.add_batch(
|
||||||
|
fqme=fqme,
|
||||||
|
timeframe=timeframe,
|
||||||
|
rects=rect_specs,
|
||||||
|
arrows=arrow_specs,
|
||||||
|
texts=text_specs,
|
||||||
|
show_individual_arrows=show_individual_arrows,
|
||||||
|
)
|
||||||
|
profiler('batch `.add_batch()` IPC call complete')
|
||||||
|
|
||||||
|
# build aids dict from batch results
|
||||||
|
for aid in result['rects']:
|
||||||
|
aids[aid] = {'type': 'rect'}
|
||||||
|
for aid in result['arrows']:
|
||||||
|
aids[aid] = {'type': 'arrow'}
|
||||||
|
for aid in result['texts']:
|
||||||
|
aids[aid] = {'type': 'text'}
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
f'Batch submission complete: {len(aids)} annotation(s) '
|
||||||
|
f'created'
|
||||||
|
)
|
||||||
|
profiler('built aids result dict')
|
||||||
|
|
||||||
|
# tell chart to redraw all its graphics view layers
|
||||||
await actl.redraw(
|
await actl.redraw(
|
||||||
fqme=fqme,
|
fqme=fqme,
|
||||||
timeframe=timeframe,
|
timeframe=timeframe,
|
||||||
)
|
)
|
||||||
|
profiler('final `.redraw()` after annot creation')
|
||||||
|
|
||||||
return aids
|
return aids
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ from __future__ import annotations
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import platform
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import (
|
from typing import (
|
||||||
|
|
@ -58,7 +59,10 @@ from piker.brokers import NoData
|
||||||
from piker.accounting import (
|
from piker.accounting import (
|
||||||
MktPair,
|
MktPair,
|
||||||
)
|
)
|
||||||
from piker.log import get_logger
|
from piker.log import (
|
||||||
|
get_logger,
|
||||||
|
get_console_log,
|
||||||
|
)
|
||||||
from ..data._sharedmem import (
|
from ..data._sharedmem import (
|
||||||
maybe_open_shm_array,
|
maybe_open_shm_array,
|
||||||
ShmArray,
|
ShmArray,
|
||||||
|
|
@ -248,10 +252,20 @@ async def maybe_fill_null_segments(
|
||||||
end_dt=end_dt,
|
end_dt=end_dt,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if array.size == 0:
|
||||||
|
log.warning(
|
||||||
|
f'Valid gap from backend ??\n'
|
||||||
|
f'{end_dt} -> {start_dt}\n'
|
||||||
|
)
|
||||||
|
# ?TODO? do we want to remove the nulls and push
|
||||||
|
# the close price here for the gap duration?
|
||||||
|
await tractor.pause()
|
||||||
|
break
|
||||||
|
|
||||||
if (
|
if (
|
||||||
frame_start_dt := (
|
frame_start_dt := (from_timestamp(array['time'][0]))
|
||||||
from_timestamp(array['time'][0])
|
<
|
||||||
) < backfill_until_dt
|
backfill_until_dt
|
||||||
):
|
):
|
||||||
log.error(
|
log.error(
|
||||||
f'Invalid frame_start !?\n'
|
f'Invalid frame_start !?\n'
|
||||||
|
|
@ -613,10 +627,17 @@ async def start_backfill(
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log.warning(
|
log.warning(
|
||||||
'0 BARS TO PUSH after diff!?\n'
|
f'0 BARS TO PUSH after diff!?\n'
|
||||||
f'{next_start_dt} -> {last_start_dt}'
|
f'{next_start_dt} -> {last_start_dt}'
|
||||||
|
f'\n'
|
||||||
|
f'This might mean we rxed a gap frame which starts BEFORE,\n'
|
||||||
|
f'backfill_until_dt: {backfill_until_dt}\n'
|
||||||
|
f'end_dt_param: {end_dt_param}\n'
|
||||||
|
|
||||||
)
|
)
|
||||||
await tractor.pause()
|
# XXX, to debug it and be sure.
|
||||||
|
# await tractor.pause()
|
||||||
|
break
|
||||||
|
|
||||||
# Check if we're about to exceed buffer capacity BEFORE
|
# Check if we're about to exceed buffer capacity BEFORE
|
||||||
# attempting the push
|
# attempting the push
|
||||||
|
|
@ -719,12 +740,21 @@ async def start_backfill(
|
||||||
# including the dst[/src] source asset token. SO,
|
# including the dst[/src] source asset token. SO,
|
||||||
# 'tsla.nasdaq.ib' over 'tsla/usd.nasdaq.ib' for
|
# 'tsla.nasdaq.ib' over 'tsla/usd.nasdaq.ib' for
|
||||||
# historical reasons ONLY.
|
# historical reasons ONLY.
|
||||||
if mkt.dst.atype not in {
|
if (
|
||||||
|
mkt.dst.atype not in {
|
||||||
'crypto',
|
'crypto',
|
||||||
'crypto_currency',
|
'crypto_currency',
|
||||||
'fiat', # a "forex pair"
|
'fiat', # a "forex pair"
|
||||||
'perpetual_future', # stupid "perps" from cex land
|
'perpetual_future', # stupid "perps" from cex land
|
||||||
}:
|
}
|
||||||
|
and not (
|
||||||
|
mkt.src.atype == 'crypto_currency'
|
||||||
|
and
|
||||||
|
mkt.dst.atype in {
|
||||||
|
'future',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
):
|
||||||
col_sym_key: str = mkt.get_fqme(
|
col_sym_key: str = mkt.get_fqme(
|
||||||
delim_char='',
|
delim_char='',
|
||||||
without_src=True,
|
without_src=True,
|
||||||
|
|
@ -1368,6 +1398,10 @@ async def manage_history(
|
||||||
engages.
|
engages.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
get_console_log(
|
||||||
|
name=__name__,
|
||||||
|
level=loglevel,
|
||||||
|
)
|
||||||
# TODO: is there a way to make each shm file key
|
# TODO: is there a way to make each shm file key
|
||||||
# actor-tree-discovery-addr unique so we avoid collisions
|
# actor-tree-discovery-addr unique so we avoid collisions
|
||||||
# when doing tests which also allocate shms for certain instruments
|
# when doing tests which also allocate shms for certain instruments
|
||||||
|
|
@ -1380,13 +1414,20 @@ async def manage_history(
|
||||||
service: str = name.rstrip(f'.{mod.name}')
|
service: str = name.rstrip(f'.{mod.name}')
|
||||||
fqme: str = mkt.get_fqme(delim_char='')
|
fqme: str = mkt.get_fqme(delim_char='')
|
||||||
|
|
||||||
|
key: str = f'piker.{service}[{uuid[:16]}].{fqme}'
|
||||||
|
# use a short hash of the `fqme` to deal with macOS
|
||||||
|
# file-name-len limit..
|
||||||
|
if platform.system() == 'Darwin':
|
||||||
|
import hashlib
|
||||||
|
fqme_hash: str = hashlib.md5(fqme.encode()).hexdigest()[:8]
|
||||||
|
key: str = f'{uuid[:8]}_{fqme_hash}'
|
||||||
|
|
||||||
# (maybe) allocate shm array for this broker/symbol which will
|
# (maybe) allocate shm array for this broker/symbol which will
|
||||||
# be used for fast near-term history capture and processing.
|
# be used for fast near-term history capture and processing.
|
||||||
hist_shm, opened = maybe_open_shm_array(
|
hist_shm, opened = maybe_open_shm_array(
|
||||||
size=_default_hist_size,
|
size=_default_hist_size,
|
||||||
append_start_index=_hist_buffer_start,
|
append_start_index=_hist_buffer_start,
|
||||||
|
key=f'{key}.hist',
|
||||||
key=f'piker.{service}[{uuid[:16]}].{fqme}.hist',
|
|
||||||
|
|
||||||
# use any broker defined ohlc dtype:
|
# use any broker defined ohlc dtype:
|
||||||
dtype=getattr(mod, '_ohlc_dtype', def_iohlcv_fields),
|
dtype=getattr(mod, '_ohlc_dtype', def_iohlcv_fields),
|
||||||
|
|
@ -1405,7 +1446,7 @@ async def manage_history(
|
||||||
rt_shm, opened = maybe_open_shm_array(
|
rt_shm, opened = maybe_open_shm_array(
|
||||||
size=_default_rt_size,
|
size=_default_rt_size,
|
||||||
append_start_index=_rt_buffer_start,
|
append_start_index=_rt_buffer_start,
|
||||||
key=f'piker.{service}[{uuid[:16]}].{fqme}.rt',
|
key=f'{key}.rt',
|
||||||
|
|
||||||
# use any broker defined ohlc dtype:
|
# use any broker defined ohlc dtype:
|
||||||
dtype=getattr(mod, '_ohlc_dtype', def_iohlcv_fields),
|
dtype=getattr(mod, '_ohlc_dtype', def_iohlcv_fields),
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,11 @@ from pyqtgraph import (
|
||||||
Point,
|
Point,
|
||||||
functions as fn,
|
functions as fn,
|
||||||
Color,
|
Color,
|
||||||
|
GraphicsObject,
|
||||||
)
|
)
|
||||||
|
from pyqtgraph.Qt import internals
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import pyqtgraph as pg
|
||||||
|
|
||||||
from piker.ui.qt import (
|
from piker.ui.qt import (
|
||||||
QtCore,
|
QtCore,
|
||||||
|
|
@ -35,6 +38,10 @@ from piker.ui.qt import (
|
||||||
QRectF,
|
QRectF,
|
||||||
QGraphicsPathItem,
|
QGraphicsPathItem,
|
||||||
)
|
)
|
||||||
|
from piker.ui._style import hcolor
|
||||||
|
from piker.log import get_logger
|
||||||
|
|
||||||
|
log = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def mk_marker_path(
|
def mk_marker_path(
|
||||||
|
|
@ -104,7 +111,7 @@ def mk_marker_path(
|
||||||
|
|
||||||
class LevelMarker(QGraphicsPathItem):
|
class LevelMarker(QGraphicsPathItem):
|
||||||
'''
|
'''
|
||||||
An arrow marker path graphich which redraws itself
|
An arrow marker path graphic which redraws itself
|
||||||
to the specified view coordinate level on each paint cycle.
|
to the specified view coordinate level on each paint cycle.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
@ -251,9 +258,9 @@ def qgo_draw_markers(
|
||||||
|
|
||||||
) -> float:
|
) -> float:
|
||||||
'''
|
'''
|
||||||
Paint markers in ``pg.GraphicsItem`` style by first
|
Paint markers in ``pg.GraphicsItem`` style by first removing the
|
||||||
removing the view transform for the painter, drawing the markers
|
view transform for the painter, drawing the markers in scene
|
||||||
in scene coords, then restoring the view coords.
|
coords, then restoring the view coords.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# paint markers in native coordinate system
|
# paint markers in native coordinate system
|
||||||
|
|
@ -295,3 +302,449 @@ def qgo_draw_markers(
|
||||||
|
|
||||||
p.setTransform(orig_tr)
|
p.setTransform(orig_tr)
|
||||||
return max(sizes)
|
return max(sizes)
|
||||||
|
|
||||||
|
|
||||||
|
class GapAnnotations(GraphicsObject):
|
||||||
|
'''
|
||||||
|
Batch-rendered gap annotations using Qt's efficient drawing
|
||||||
|
APIs.
|
||||||
|
|
||||||
|
Instead of creating individual `QGraphicsItem` instances per
|
||||||
|
gap (which is very slow for 1000+ gaps), this class stores all
|
||||||
|
gap rectangles and arrows in numpy-backed arrays and renders
|
||||||
|
them in single batch paint calls.
|
||||||
|
|
||||||
|
Performance: ~1000x faster than individual items for large gap
|
||||||
|
counts.
|
||||||
|
|
||||||
|
Based on patterns from:
|
||||||
|
- `pyqtgraph.BarGraphItem` (batch rect rendering)
|
||||||
|
- `pyqtgraph.ScatterPlotItem` (fragment rendering)
|
||||||
|
- `piker.ui._curve.FlowGraphic` (single path pattern)
|
||||||
|
|
||||||
|
'''
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
gap_specs: list[dict],
|
||||||
|
array: np.ndarray|None = None,
|
||||||
|
color: str = 'dad_blue',
|
||||||
|
alpha: int = 169,
|
||||||
|
arrow_size: float = 10.0,
|
||||||
|
fqme: str|None = None,
|
||||||
|
timeframe: float|None = None,
|
||||||
|
) -> None:
|
||||||
|
'''
|
||||||
|
gap_specs: list of dicts with keys:
|
||||||
|
- start_pos: (x, y) tuple for left corner of rect
|
||||||
|
- end_pos: (x, y) tuple for right corner of rect
|
||||||
|
- arrow_x: x position for arrow
|
||||||
|
- arrow_y: y position for arrow
|
||||||
|
- pointing: 'up' or 'down' for arrow direction
|
||||||
|
- start_time: (optional) timestamp for repositioning
|
||||||
|
- end_time: (optional) timestamp for repositioning
|
||||||
|
|
||||||
|
array: optional OHLC numpy array for repositioning on
|
||||||
|
backfill updates (when abs-index changes)
|
||||||
|
|
||||||
|
fqme: symbol name for these gaps (for logging/debugging)
|
||||||
|
|
||||||
|
timeframe: period in seconds that these gaps were
|
||||||
|
detected on (used to skip reposition when
|
||||||
|
called with wrong timeframe's array)
|
||||||
|
|
||||||
|
'''
|
||||||
|
super().__init__()
|
||||||
|
self._gap_specs = gap_specs
|
||||||
|
self._array = array
|
||||||
|
self._fqme = fqme
|
||||||
|
self._timeframe = timeframe
|
||||||
|
n_gaps = len(gap_specs)
|
||||||
|
|
||||||
|
# shared pen/brush matching original SelectRect/ArrowItem style
|
||||||
|
base_color = pg.mkColor(hcolor(color))
|
||||||
|
|
||||||
|
# rect pen: base color, fully opaque for outline
|
||||||
|
self._rect_pen = pg.mkPen(base_color, width=1)
|
||||||
|
|
||||||
|
# rect brush: base color with alpha=66 (SelectRect default)
|
||||||
|
rect_fill = pg.mkColor(hcolor(color))
|
||||||
|
rect_fill.setAlpha(66)
|
||||||
|
self._rect_brush = pg.functions.mkBrush(rect_fill)
|
||||||
|
|
||||||
|
# arrow pen: same as rects
|
||||||
|
self._arrow_pen = pg.mkPen(base_color, width=1)
|
||||||
|
|
||||||
|
# arrow brush: base color with user-specified alpha (default 169)
|
||||||
|
arrow_fill = pg.mkColor(hcolor(color))
|
||||||
|
arrow_fill.setAlpha(alpha)
|
||||||
|
self._arrow_brush = pg.functions.mkBrush(arrow_fill)
|
||||||
|
|
||||||
|
# allocate rect array using Qt's efficient storage
|
||||||
|
self._rectarray = internals.PrimitiveArray(
|
||||||
|
QtCore.QRectF,
|
||||||
|
4,
|
||||||
|
)
|
||||||
|
self._rectarray.resize(n_gaps)
|
||||||
|
rect_memory = self._rectarray.ndarray()
|
||||||
|
|
||||||
|
# fill rect array from gap specs
|
||||||
|
for (
|
||||||
|
i,
|
||||||
|
spec,
|
||||||
|
) in enumerate(gap_specs):
|
||||||
|
(
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
) = spec['start_pos']
|
||||||
|
(
|
||||||
|
end_x,
|
||||||
|
end_y,
|
||||||
|
) = spec['end_pos']
|
||||||
|
|
||||||
|
# QRectF expects (x, y, width, height)
|
||||||
|
rect_memory[i, 0] = start_x
|
||||||
|
rect_memory[i, 1] = min(start_y, end_y)
|
||||||
|
rect_memory[i, 2] = end_x - start_x
|
||||||
|
rect_memory[i, 3] = abs(end_y - start_y)
|
||||||
|
|
||||||
|
# build single QPainterPath for all arrows
|
||||||
|
self._arrow_path = QtGui.QPainterPath()
|
||||||
|
self._arrow_size = arrow_size
|
||||||
|
|
||||||
|
for spec in gap_specs:
|
||||||
|
arrow_x = spec['arrow_x']
|
||||||
|
arrow_y = spec['arrow_y']
|
||||||
|
pointing = spec['pointing']
|
||||||
|
|
||||||
|
# create arrow polygon
|
||||||
|
if pointing == 'down':
|
||||||
|
# arrow points downward
|
||||||
|
arrow_poly = QtGui.QPolygonF([
|
||||||
|
QPointF(arrow_x, arrow_y), # tip
|
||||||
|
QPointF(
|
||||||
|
arrow_x - arrow_size/2,
|
||||||
|
arrow_y - arrow_size,
|
||||||
|
), # left
|
||||||
|
QPointF(
|
||||||
|
arrow_x + arrow_size/2,
|
||||||
|
arrow_y - arrow_size,
|
||||||
|
), # right
|
||||||
|
])
|
||||||
|
else: # up
|
||||||
|
# arrow points upward
|
||||||
|
arrow_poly = QtGui.QPolygonF([
|
||||||
|
QPointF(arrow_x, arrow_y), # tip
|
||||||
|
QPointF(
|
||||||
|
arrow_x - arrow_size/2,
|
||||||
|
arrow_y + arrow_size,
|
||||||
|
), # left
|
||||||
|
QPointF(
|
||||||
|
arrow_x + arrow_size/2,
|
||||||
|
arrow_y + arrow_size,
|
||||||
|
), # right
|
||||||
|
])
|
||||||
|
|
||||||
|
self._arrow_path.addPolygon(arrow_poly)
|
||||||
|
self._arrow_path.closeSubpath()
|
||||||
|
|
||||||
|
# cache bounding rect
|
||||||
|
self._br: QRectF|None = None
|
||||||
|
|
||||||
|
def boundingRect(self) -> QRectF:
|
||||||
|
'''
|
||||||
|
Compute bounding rect from rect array and arrow path.
|
||||||
|
|
||||||
|
'''
|
||||||
|
if self._br is not None:
|
||||||
|
return self._br
|
||||||
|
|
||||||
|
# get rect bounds
|
||||||
|
rect_memory = self._rectarray.ndarray()
|
||||||
|
if len(rect_memory) == 0:
|
||||||
|
self._br = QRectF()
|
||||||
|
return self._br
|
||||||
|
|
||||||
|
x_min = rect_memory[:, 0].min()
|
||||||
|
y_min = rect_memory[:, 1].min()
|
||||||
|
x_max = (rect_memory[:, 0] + rect_memory[:, 2]).max()
|
||||||
|
y_max = (rect_memory[:, 1] + rect_memory[:, 3]).max()
|
||||||
|
|
||||||
|
# expand for arrow path
|
||||||
|
arrow_br = self._arrow_path.boundingRect()
|
||||||
|
x_min = min(x_min, arrow_br.left())
|
||||||
|
y_min = min(y_min, arrow_br.top())
|
||||||
|
x_max = max(x_max, arrow_br.right())
|
||||||
|
y_max = max(y_max, arrow_br.bottom())
|
||||||
|
|
||||||
|
self._br = QRectF(
|
||||||
|
x_min,
|
||||||
|
y_min,
|
||||||
|
x_max - x_min,
|
||||||
|
y_max - y_min,
|
||||||
|
)
|
||||||
|
return self._br
|
||||||
|
|
||||||
|
def paint(
|
||||||
|
self,
|
||||||
|
p: QtGui.QPainter,
|
||||||
|
opt: QtWidgets.QStyleOptionGraphicsItem,
|
||||||
|
w: QtWidgets.QWidget,
|
||||||
|
) -> None:
|
||||||
|
'''
|
||||||
|
Batch render all rects and arrows in minimal paint calls.
|
||||||
|
|
||||||
|
'''
|
||||||
|
# draw all rects in single batch call (data coordinates)
|
||||||
|
p.setPen(self._rect_pen)
|
||||||
|
p.setBrush(self._rect_brush)
|
||||||
|
drawargs = self._rectarray.drawargs()
|
||||||
|
p.drawRects(*drawargs)
|
||||||
|
|
||||||
|
# draw arrows in scene/pixel coordinates so they maintain
|
||||||
|
# size regardless of zoom level
|
||||||
|
orig_tr = p.transform()
|
||||||
|
p.resetTransform()
|
||||||
|
|
||||||
|
# rebuild arrow path in scene coordinates
|
||||||
|
arrow_path_scene = QtGui.QPainterPath()
|
||||||
|
|
||||||
|
# arrow geometry matching pg.ArrowItem defaults
|
||||||
|
# headLen=10, headWidth=2.222
|
||||||
|
# headWidth is the half-width (center to edge distance)
|
||||||
|
head_len = self._arrow_size
|
||||||
|
head_width = head_len * 0.2222 # 2.222 at size=10
|
||||||
|
|
||||||
|
for spec in self._gap_specs:
|
||||||
|
if 'arrow_x' not in spec:
|
||||||
|
continue
|
||||||
|
|
||||||
|
arrow_x = spec['arrow_x']
|
||||||
|
arrow_y = spec['arrow_y']
|
||||||
|
pointing = spec['pointing']
|
||||||
|
|
||||||
|
# transform data coords to scene coords
|
||||||
|
scene_pt = orig_tr.map(QPointF(arrow_x, arrow_y))
|
||||||
|
sx = scene_pt.x()
|
||||||
|
sy = scene_pt.y()
|
||||||
|
|
||||||
|
# create arrow polygon in scene/pixel coords
|
||||||
|
# matching pg.ArrowItem geometry but rotated for up/down
|
||||||
|
if pointing == 'down':
|
||||||
|
# tip points downward (negative y direction)
|
||||||
|
arrow_poly = QtGui.QPolygonF([
|
||||||
|
QPointF(sx, sy), # tip
|
||||||
|
QPointF(
|
||||||
|
sx - head_width,
|
||||||
|
sy - head_len,
|
||||||
|
), # left base
|
||||||
|
QPointF(
|
||||||
|
sx + head_width,
|
||||||
|
sy - head_len,
|
||||||
|
), # right base
|
||||||
|
])
|
||||||
|
else: # up
|
||||||
|
# tip points upward (positive y direction)
|
||||||
|
arrow_poly = QtGui.QPolygonF([
|
||||||
|
QPointF(sx, sy), # tip
|
||||||
|
QPointF(
|
||||||
|
sx - head_width,
|
||||||
|
sy + head_len,
|
||||||
|
), # left base
|
||||||
|
QPointF(
|
||||||
|
sx + head_width,
|
||||||
|
sy + head_len,
|
||||||
|
), # right base
|
||||||
|
])
|
||||||
|
|
||||||
|
arrow_path_scene.addPolygon(arrow_poly)
|
||||||
|
arrow_path_scene.closeSubpath()
|
||||||
|
|
||||||
|
p.setPen(self._arrow_pen)
|
||||||
|
p.setBrush(self._arrow_brush)
|
||||||
|
p.drawPath(arrow_path_scene)
|
||||||
|
|
||||||
|
# restore original transform
|
||||||
|
p.setTransform(orig_tr)
|
||||||
|
|
||||||
|
def reposition(
|
||||||
|
self,
|
||||||
|
array: np.ndarray|None = None,
|
||||||
|
fqme: str|None = None,
|
||||||
|
timeframe: float|None = None,
|
||||||
|
) -> None:
|
||||||
|
'''
|
||||||
|
Reposition all annotations based on timestamps.
|
||||||
|
|
||||||
|
Used when viz is updated (eg during backfill) and abs-index
|
||||||
|
range changes - we need to lookup new indices from timestamps.
|
||||||
|
|
||||||
|
'''
|
||||||
|
# skip reposition if timeframe doesn't match
|
||||||
|
# (e.g., 1s gaps being repositioned with 60s array)
|
||||||
|
if (
|
||||||
|
timeframe is not None
|
||||||
|
and
|
||||||
|
self._timeframe is not None
|
||||||
|
and
|
||||||
|
timeframe != self._timeframe
|
||||||
|
):
|
||||||
|
log.debug(
|
||||||
|
f'Skipping reposition for {self._fqme} gaps:\n'
|
||||||
|
f' gap timeframe: {self._timeframe}s\n'
|
||||||
|
f' array timeframe: {timeframe}s\n'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if array is None:
|
||||||
|
array = self._array
|
||||||
|
|
||||||
|
if array is None:
|
||||||
|
log.warning(
|
||||||
|
'GapAnnotations.reposition() called but no array '
|
||||||
|
'provided'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# collect all unique timestamps we need to lookup
|
||||||
|
timestamps: set[float] = set()
|
||||||
|
for spec in self._gap_specs:
|
||||||
|
if spec.get('start_time') is not None:
|
||||||
|
timestamps.add(spec['start_time'])
|
||||||
|
if spec.get('end_time') is not None:
|
||||||
|
timestamps.add(spec['end_time'])
|
||||||
|
if spec.get('time') is not None:
|
||||||
|
timestamps.add(spec['time'])
|
||||||
|
|
||||||
|
# vectorized timestamp -> row lookup using binary search
|
||||||
|
time_to_row: dict[float, dict] = {}
|
||||||
|
if timestamps:
|
||||||
|
import numpy as np
|
||||||
|
time_arr = array['time']
|
||||||
|
ts_array = np.array(list(timestamps))
|
||||||
|
|
||||||
|
search_indices = np.searchsorted(
|
||||||
|
time_arr,
|
||||||
|
ts_array,
|
||||||
|
)
|
||||||
|
|
||||||
|
# vectorized bounds check and exact match verification
|
||||||
|
valid_mask = (
|
||||||
|
(search_indices < len(array))
|
||||||
|
& (time_arr[search_indices] == ts_array)
|
||||||
|
)
|
||||||
|
|
||||||
|
valid_indices = search_indices[valid_mask]
|
||||||
|
valid_timestamps = ts_array[valid_mask]
|
||||||
|
matched_rows = array[valid_indices]
|
||||||
|
|
||||||
|
time_to_row = {
|
||||||
|
float(ts): {
|
||||||
|
'index': float(row['index']),
|
||||||
|
'open': float(row['open']),
|
||||||
|
'close': float(row['close']),
|
||||||
|
}
|
||||||
|
for ts, row in zip(
|
||||||
|
valid_timestamps,
|
||||||
|
matched_rows,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
# rebuild rect array from gap specs with new indices
|
||||||
|
rect_memory = self._rectarray.ndarray()
|
||||||
|
|
||||||
|
for (
|
||||||
|
i,
|
||||||
|
spec,
|
||||||
|
) in enumerate(self._gap_specs):
|
||||||
|
start_time = spec.get('start_time')
|
||||||
|
end_time = spec.get('end_time')
|
||||||
|
|
||||||
|
if (
|
||||||
|
start_time is None
|
||||||
|
or end_time is None
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
start_row = time_to_row.get(start_time)
|
||||||
|
end_row = time_to_row.get(end_time)
|
||||||
|
|
||||||
|
if (
|
||||||
|
start_row is None
|
||||||
|
or end_row is None
|
||||||
|
):
|
||||||
|
log.warning(
|
||||||
|
f'Timestamp lookup failed for gap[{i}] during '
|
||||||
|
f'reposition:\n'
|
||||||
|
f' fqme: {fqme}\n'
|
||||||
|
f' timeframe: {timeframe}s\n'
|
||||||
|
f' start_time: {start_time}\n'
|
||||||
|
f' end_time: {end_time}\n'
|
||||||
|
f' array time range: '
|
||||||
|
f'{array["time"][0]} -> {array["time"][-1]}\n'
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
start_idx = start_row['index']
|
||||||
|
end_idx = end_row['index']
|
||||||
|
start_close = start_row['close']
|
||||||
|
end_open = end_row['open']
|
||||||
|
|
||||||
|
from_idx: float = 0.16 - 0.06
|
||||||
|
start_x = start_idx + 1 - from_idx
|
||||||
|
end_x = end_idx + from_idx
|
||||||
|
|
||||||
|
# update rect in array
|
||||||
|
rect_memory[i, 0] = start_x
|
||||||
|
rect_memory[i, 1] = min(start_close, end_open)
|
||||||
|
rect_memory[i, 2] = end_x - start_x
|
||||||
|
rect_memory[i, 3] = abs(end_open - start_close)
|
||||||
|
|
||||||
|
# rebuild arrow path with new indices
|
||||||
|
self._arrow_path.clear()
|
||||||
|
|
||||||
|
for spec in self._gap_specs:
|
||||||
|
time_val = spec.get('time')
|
||||||
|
if time_val is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
arrow_row = time_to_row.get(time_val)
|
||||||
|
if arrow_row is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
arrow_x = arrow_row['index']
|
||||||
|
arrow_y = arrow_row['close']
|
||||||
|
pointing = spec['pointing']
|
||||||
|
|
||||||
|
# create arrow polygon
|
||||||
|
if pointing == 'down':
|
||||||
|
arrow_poly = QtGui.QPolygonF([
|
||||||
|
QPointF(arrow_x, arrow_y),
|
||||||
|
QPointF(
|
||||||
|
arrow_x - self._arrow_size/2,
|
||||||
|
arrow_y - self._arrow_size,
|
||||||
|
),
|
||||||
|
QPointF(
|
||||||
|
arrow_x + self._arrow_size/2,
|
||||||
|
arrow_y - self._arrow_size,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
else: # up
|
||||||
|
arrow_poly = QtGui.QPolygonF([
|
||||||
|
QPointF(arrow_x, arrow_y),
|
||||||
|
QPointF(
|
||||||
|
arrow_x - self._arrow_size/2,
|
||||||
|
arrow_y + self._arrow_size,
|
||||||
|
),
|
||||||
|
QPointF(
|
||||||
|
arrow_x + self._arrow_size/2,
|
||||||
|
arrow_y + self._arrow_size,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
self._arrow_path.addPolygon(arrow_poly)
|
||||||
|
self._arrow_path.closeSubpath()
|
||||||
|
|
||||||
|
# invalidate bounding rect cache
|
||||||
|
self._br = None
|
||||||
|
self.prepareGeometryChange()
|
||||||
|
self.update()
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,8 @@ async def increment_history_view(
|
||||||
hist_chart: ChartPlotWidget = ds.hist_chart
|
hist_chart: ChartPlotWidget = ds.hist_chart
|
||||||
hist_viz: Viz = ds.hist_viz
|
hist_viz: Viz = ds.hist_viz
|
||||||
# viz: Viz = ds.viz
|
# viz: Viz = ds.viz
|
||||||
assert 'hist' in hist_viz.shm.token['shm_name']
|
# Ensure the "history" shm-buffer is what's reffed.
|
||||||
|
assert hist_viz.shm.token['shm_name'].endswith('.hist')
|
||||||
# name: str = hist_viz.name
|
# name: str = hist_viz.name
|
||||||
|
|
||||||
# TODO: seems this is more reliable at keeping the slow
|
# TODO: seems this is more reliable at keeping the slow
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ class ArrowEditor(Struct):
|
||||||
'''
|
'''
|
||||||
uid: str = arrow._uid
|
uid: str = arrow._uid
|
||||||
arrows: list[pg.ArrowItem] = self._arrows[uid]
|
arrows: list[pg.ArrowItem] = self._arrows[uid]
|
||||||
log.info(
|
log.debug(
|
||||||
f'Removing arrow from views\n'
|
f'Removing arrow from views\n'
|
||||||
f'uid: {uid!r}\n'
|
f'uid: {uid!r}\n'
|
||||||
f'{arrow!r}\n'
|
f'{arrow!r}\n'
|
||||||
|
|
@ -286,7 +286,9 @@ class LineEditor(Struct):
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line.show_labels()
|
line.show_labels()
|
||||||
line.hide_markers()
|
line.hide_markers()
|
||||||
log.debug(f'Level active for level: {line.value()}')
|
log.debug(
|
||||||
|
f'Line active @ level: {line.value()!r}'
|
||||||
|
)
|
||||||
# TODO: other flashy things to indicate the order is active
|
# TODO: other flashy things to indicate the order is active
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
@ -329,7 +331,11 @@ class LineEditor(Struct):
|
||||||
if line in hovered:
|
if line in hovered:
|
||||||
hovered.remove(line)
|
hovered.remove(line)
|
||||||
|
|
||||||
log.debug(f'deleting {line} with oid: {uuid}')
|
log.debug(
|
||||||
|
f'Deleting level-line\n'
|
||||||
|
f'line: {line!r}\n'
|
||||||
|
f'oid: {uuid!r}\n'
|
||||||
|
)
|
||||||
line.delete()
|
line.delete()
|
||||||
|
|
||||||
# make sure the xhair doesn't get left off
|
# make sure the xhair doesn't get left off
|
||||||
|
|
@ -337,7 +343,11 @@ class LineEditor(Struct):
|
||||||
cursor.show_xhair()
|
cursor.show_xhair()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log.warning(f'Could not find line for {line}')
|
log.warning(
|
||||||
|
f'Could not find line for removal ??\n'
|
||||||
|
f'\n'
|
||||||
|
f'{line!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
@ -569,11 +579,11 @@ class SelectRect(QtWidgets.QGraphicsRectItem):
|
||||||
if update_label:
|
if update_label:
|
||||||
self.init_label(view_rect)
|
self.init_label(view_rect)
|
||||||
|
|
||||||
print(
|
log.debug(
|
||||||
'SelectRect modify:\n'
|
f'SelectRect modify,\n'
|
||||||
f'QRectF: {view_rect}\n'
|
f'QRectF: {view_rect}\n'
|
||||||
f'start_pos: {start_pos}\n'
|
f'start_pos: {start_pos!r}\n'
|
||||||
f'end_pos: {end_pos}\n'
|
f'end_pos: {end_pos!r}\n'
|
||||||
)
|
)
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
|
|
@ -640,8 +650,11 @@ class SelectRect(QtWidgets.QGraphicsRectItem):
|
||||||
dmn=dmn,
|
dmn=dmn,
|
||||||
))
|
))
|
||||||
|
|
||||||
# print(f'x2, y2: {(x2, y2)}')
|
# tracing
|
||||||
# print(f'xmn, ymn: {(xmn, ymx)}')
|
# log.info(
|
||||||
|
# f'x2, y2: {(x2, y2)}\n'
|
||||||
|
# f'xmn, ymn: {(xmn, ymx)}\n'
|
||||||
|
# )
|
||||||
|
|
||||||
label_anchor = Point(
|
label_anchor = Point(
|
||||||
xmx + 2,
|
xmx + 2,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ from piker.ui.qt import (
|
||||||
QtGui,
|
QtGui,
|
||||||
QGraphicsPathItem,
|
QGraphicsPathItem,
|
||||||
QStyleOptionGraphicsItem,
|
QStyleOptionGraphicsItem,
|
||||||
QGraphicsItem,
|
|
||||||
QGraphicsScene,
|
QGraphicsScene,
|
||||||
QWidget,
|
QWidget,
|
||||||
QPointF,
|
QPointF,
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ a chart from some other actor.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from contextlib import (
|
from contextlib import (
|
||||||
asynccontextmanager as acm,
|
asynccontextmanager as acm,
|
||||||
|
contextmanager as cm,
|
||||||
AsyncExitStack,
|
AsyncExitStack,
|
||||||
)
|
)
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
@ -46,6 +47,7 @@ from piker.log import get_logger
|
||||||
from piker.types import Struct
|
from piker.types import Struct
|
||||||
from piker.service import find_service
|
from piker.service import find_service
|
||||||
from piker.brokers import SymbolNotFound
|
from piker.brokers import SymbolNotFound
|
||||||
|
from piker.toolz import Profiler
|
||||||
from piker.ui.qt import (
|
from piker.ui.qt import (
|
||||||
QGraphicsItem,
|
QGraphicsItem,
|
||||||
)
|
)
|
||||||
|
|
@ -98,6 +100,8 @@ def rm_annot(
|
||||||
annot: ArrowEditor|SelectRect|pg.TextItem
|
annot: ArrowEditor|SelectRect|pg.TextItem
|
||||||
) -> bool:
|
) -> bool:
|
||||||
global _editors
|
global _editors
|
||||||
|
from piker.ui._annotate import GapAnnotations
|
||||||
|
|
||||||
match annot:
|
match annot:
|
||||||
case pg.ArrowItem():
|
case pg.ArrowItem():
|
||||||
editor = _editors[annot._uid]
|
editor = _editors[annot._uid]
|
||||||
|
|
@ -122,9 +126,35 @@ def rm_annot(
|
||||||
scene.removeItem(annot)
|
scene.removeItem(annot)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
case GapAnnotations():
|
||||||
|
scene = annot.scene()
|
||||||
|
if scene:
|
||||||
|
scene.removeItem(annot)
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@cm
|
||||||
|
def no_qt_updates(*items):
|
||||||
|
'''
|
||||||
|
Disable Qt widget/item updates during context to batch
|
||||||
|
render operations and only trigger single repaint on exit.
|
||||||
|
|
||||||
|
Accepts both QWidgets and QGraphicsItems.
|
||||||
|
|
||||||
|
'''
|
||||||
|
for item in items:
|
||||||
|
if hasattr(item, 'setUpdatesEnabled'):
|
||||||
|
item.setUpdatesEnabled(False)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
for item in items:
|
||||||
|
if hasattr(item, 'setUpdatesEnabled'):
|
||||||
|
item.setUpdatesEnabled(True)
|
||||||
|
|
||||||
|
|
||||||
async def serve_rc_annots(
|
async def serve_rc_annots(
|
||||||
ipc_key: str,
|
ipc_key: str,
|
||||||
annot_req_stream: MsgStream,
|
annot_req_stream: MsgStream,
|
||||||
|
|
@ -429,6 +459,333 @@ async def serve_rc_annots(
|
||||||
aids.add(aid)
|
aids.add(aid)
|
||||||
await annot_req_stream.send(aid)
|
await annot_req_stream.send(aid)
|
||||||
|
|
||||||
|
case {
|
||||||
|
'cmd': 'batch',
|
||||||
|
'fqme': fqme,
|
||||||
|
'timeframe': timeframe,
|
||||||
|
'rects': list(rect_specs),
|
||||||
|
'arrows': list(arrow_specs),
|
||||||
|
'texts': list(text_specs),
|
||||||
|
'show_individual_arrows': bool(show_individual_arrows),
|
||||||
|
}:
|
||||||
|
# batch submission handler - process multiple
|
||||||
|
# annotations in single IPC round-trip
|
||||||
|
ds: DisplayState = _dss[fqme]
|
||||||
|
try:
|
||||||
|
chart: ChartPlotWidget = {
|
||||||
|
60: ds.hist_chart,
|
||||||
|
1: ds.chart,
|
||||||
|
}[timeframe]
|
||||||
|
except KeyError:
|
||||||
|
msg: str = (
|
||||||
|
f'No chart for timeframe={timeframe}s, '
|
||||||
|
f'skipping batch annotation'
|
||||||
|
)
|
||||||
|
log.error(msg)
|
||||||
|
await annot_req_stream.send({'error': msg})
|
||||||
|
continue
|
||||||
|
|
||||||
|
cv: ChartView = chart.cv
|
||||||
|
viz: Viz = chart.get_viz(fqme)
|
||||||
|
shm = viz.shm
|
||||||
|
arr = shm.array
|
||||||
|
|
||||||
|
result: dict[str, list[int]] = {
|
||||||
|
'rects': [],
|
||||||
|
'arrows': [],
|
||||||
|
'texts': [],
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler = Profiler(
|
||||||
|
msg=(
|
||||||
|
f'Batch annotate {len(rect_specs)} gaps '
|
||||||
|
f'on {fqme}@{timeframe}s'
|
||||||
|
),
|
||||||
|
disabled=False,
|
||||||
|
delayed=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
aids_set: set[int] = ctxs[ipc_key][1]
|
||||||
|
|
||||||
|
# build unified gap_specs for GapAnnotations class
|
||||||
|
from piker.ui._annotate import GapAnnotations
|
||||||
|
|
||||||
|
gap_specs: list[dict] = []
|
||||||
|
n_gaps: int = max(
|
||||||
|
len(rect_specs),
|
||||||
|
len(arrow_specs),
|
||||||
|
)
|
||||||
|
profiler('setup batch annot creation')
|
||||||
|
|
||||||
|
# collect all unique timestamps for vectorized lookup
|
||||||
|
timestamps: list[float] = []
|
||||||
|
for rect_spec in rect_specs:
|
||||||
|
if start_time := rect_spec.get('start_time'):
|
||||||
|
timestamps.append(start_time)
|
||||||
|
if end_time := rect_spec.get('end_time'):
|
||||||
|
timestamps.append(end_time)
|
||||||
|
for arrow_spec in arrow_specs:
|
||||||
|
if time_val := arrow_spec.get('time'):
|
||||||
|
timestamps.append(time_val)
|
||||||
|
|
||||||
|
profiler('collect `timestamps: list` complet!')
|
||||||
|
|
||||||
|
# build timestamp -> row mapping using binary search
|
||||||
|
# O(m log n) instead of O(n*m) with np.isin
|
||||||
|
time_to_row: dict[float, dict] = {}
|
||||||
|
if timestamps:
|
||||||
|
import numpy as np
|
||||||
|
time_arr = arr['time']
|
||||||
|
ts_array = np.array(timestamps)
|
||||||
|
|
||||||
|
# binary search for each timestamp in sorted time array
|
||||||
|
search_indices = np.searchsorted(
|
||||||
|
time_arr,
|
||||||
|
ts_array,
|
||||||
|
)
|
||||||
|
|
||||||
|
profiler('`np.searchsorted()` complete!')
|
||||||
|
|
||||||
|
# vectorized bounds check and exact match verification
|
||||||
|
valid_mask = (
|
||||||
|
(search_indices < len(arr))
|
||||||
|
& (time_arr[search_indices] == ts_array)
|
||||||
|
)
|
||||||
|
|
||||||
|
# get all valid indices and timestamps
|
||||||
|
valid_indices = search_indices[valid_mask]
|
||||||
|
valid_timestamps = ts_array[valid_mask]
|
||||||
|
|
||||||
|
# use fancy indexing to get all rows at once
|
||||||
|
matched_rows = arr[valid_indices]
|
||||||
|
|
||||||
|
# extract fields to plain arrays BEFORE dict building
|
||||||
|
indices_arr = matched_rows['index'].astype(float)
|
||||||
|
opens_arr = matched_rows['open'].astype(float)
|
||||||
|
closes_arr = matched_rows['close'].astype(float)
|
||||||
|
|
||||||
|
profiler('extracted field arrays')
|
||||||
|
|
||||||
|
# build dict from plain arrays (much faster)
|
||||||
|
time_to_row: dict[float, dict] = {
|
||||||
|
float(ts): {
|
||||||
|
'index': idx,
|
||||||
|
'open': opn,
|
||||||
|
'close': cls,
|
||||||
|
}
|
||||||
|
for (
|
||||||
|
ts,
|
||||||
|
idx,
|
||||||
|
opn,
|
||||||
|
cls,
|
||||||
|
) in zip(
|
||||||
|
valid_timestamps,
|
||||||
|
indices_arr,
|
||||||
|
opens_arr,
|
||||||
|
closes_arr,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler('`time_to_row` creation complete!')
|
||||||
|
|
||||||
|
profiler(f'built timestamp lookup for {len(timestamps)} times')
|
||||||
|
|
||||||
|
# build gap_specs from rect+arrow specs
|
||||||
|
for i in range(n_gaps):
|
||||||
|
gap_spec: dict = {}
|
||||||
|
|
||||||
|
# get rect spec for this gap
|
||||||
|
if i < len(rect_specs):
|
||||||
|
rect_spec: dict = rect_specs[i].copy()
|
||||||
|
start_time = rect_spec.get('start_time')
|
||||||
|
end_time = rect_spec.get('end_time')
|
||||||
|
|
||||||
|
if (
|
||||||
|
start_time is not None
|
||||||
|
and end_time is not None
|
||||||
|
):
|
||||||
|
# lookup from pre-built mapping
|
||||||
|
start_row = time_to_row.get(start_time)
|
||||||
|
end_row = time_to_row.get(end_time)
|
||||||
|
|
||||||
|
if (
|
||||||
|
start_row is None
|
||||||
|
or end_row is None
|
||||||
|
):
|
||||||
|
log.warning(
|
||||||
|
f'Timestamp lookup failed for '
|
||||||
|
f'gap[{i}], skipping'
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
start_idx = start_row['index']
|
||||||
|
end_idx = end_row['index']
|
||||||
|
start_close = start_row['close']
|
||||||
|
end_open = end_row['open']
|
||||||
|
|
||||||
|
from_idx: float = 0.16 - 0.06
|
||||||
|
gap_spec['start_pos'] = (
|
||||||
|
start_idx + 1 - from_idx,
|
||||||
|
start_close,
|
||||||
|
)
|
||||||
|
gap_spec['end_pos'] = (
|
||||||
|
end_idx + from_idx,
|
||||||
|
end_open,
|
||||||
|
)
|
||||||
|
gap_spec['start_time'] = start_time
|
||||||
|
gap_spec['end_time'] = end_time
|
||||||
|
gap_spec['color'] = rect_spec.get(
|
||||||
|
'color',
|
||||||
|
'dad_blue',
|
||||||
|
)
|
||||||
|
|
||||||
|
# get arrow spec for this gap
|
||||||
|
if i < len(arrow_specs):
|
||||||
|
arrow_spec: dict = arrow_specs[i].copy()
|
||||||
|
x: float = float(arrow_spec.get('x', 0))
|
||||||
|
y: float = float(arrow_spec.get('y', 0))
|
||||||
|
time_val: float|None = arrow_spec.get('time')
|
||||||
|
|
||||||
|
# timestamp-based index lookup (only for x, NOT y!)
|
||||||
|
# y is already set to the PREVIOUS bar's close
|
||||||
|
if time_val is not None:
|
||||||
|
arrow_row = time_to_row.get(time_val)
|
||||||
|
if arrow_row is not None:
|
||||||
|
x = arrow_row['index']
|
||||||
|
# NOTE: do NOT update y! it's the
|
||||||
|
# previous bar's close, not current
|
||||||
|
else:
|
||||||
|
log.warning(
|
||||||
|
f'Arrow timestamp {time_val} not '
|
||||||
|
f'found for gap[{i}], using x={x}'
|
||||||
|
)
|
||||||
|
|
||||||
|
gap_spec['arrow_x'] = x
|
||||||
|
gap_spec['arrow_y'] = y
|
||||||
|
gap_spec['time'] = time_val
|
||||||
|
gap_spec['pointing'] = arrow_spec.get(
|
||||||
|
'pointing',
|
||||||
|
'down',
|
||||||
|
)
|
||||||
|
gap_spec['alpha'] = arrow_spec.get('alpha', 169)
|
||||||
|
|
||||||
|
gap_specs.append(gap_spec)
|
||||||
|
|
||||||
|
profiler(f'built {len(gap_specs)} gap_specs')
|
||||||
|
|
||||||
|
# create single GapAnnotations item for all gaps
|
||||||
|
if gap_specs:
|
||||||
|
gaps_item = GapAnnotations(
|
||||||
|
gap_specs=gap_specs,
|
||||||
|
array=arr,
|
||||||
|
color=gap_specs[0].get('color', 'dad_blue'),
|
||||||
|
alpha=gap_specs[0].get('alpha', 169),
|
||||||
|
arrow_size=10.0,
|
||||||
|
fqme=fqme,
|
||||||
|
timeframe=timeframe,
|
||||||
|
)
|
||||||
|
chart.plotItem.addItem(gaps_item)
|
||||||
|
|
||||||
|
# register single item for repositioning
|
||||||
|
aid: int = id(gaps_item)
|
||||||
|
annots[aid] = gaps_item
|
||||||
|
aids_set.add(aid)
|
||||||
|
result['rects'].append(aid)
|
||||||
|
profiler(
|
||||||
|
f'created GapAnnotations item for {len(gap_specs)} '
|
||||||
|
f'gaps'
|
||||||
|
)
|
||||||
|
|
||||||
|
# A/B comparison: optionally create individual arrows
|
||||||
|
# alongside batch for visual comparison
|
||||||
|
if show_individual_arrows:
|
||||||
|
godw = chart.linked.godwidget
|
||||||
|
arrows: ArrowEditor = ArrowEditor(godw=godw)
|
||||||
|
for i, spec in enumerate(gap_specs):
|
||||||
|
if 'arrow_x' not in spec:
|
||||||
|
continue
|
||||||
|
|
||||||
|
aid_str: str = str(uuid4())
|
||||||
|
arrow: pg.ArrowItem = arrows.add(
|
||||||
|
plot=chart.plotItem,
|
||||||
|
uid=aid_str,
|
||||||
|
x=spec['arrow_x'],
|
||||||
|
y=spec['arrow_y'],
|
||||||
|
pointing=spec['pointing'],
|
||||||
|
color='bracket', # different color
|
||||||
|
alpha=spec.get('alpha', 169),
|
||||||
|
headLen=10.0,
|
||||||
|
headWidth=2.222,
|
||||||
|
pxMode=True,
|
||||||
|
)
|
||||||
|
arrow._abs_x = spec['arrow_x']
|
||||||
|
arrow._abs_y = spec['arrow_y']
|
||||||
|
|
||||||
|
annots[aid_str] = arrow
|
||||||
|
_editors[aid_str] = arrows
|
||||||
|
aids_set.add(aid_str)
|
||||||
|
result['arrows'].append(aid_str)
|
||||||
|
|
||||||
|
profiler(
|
||||||
|
f'created {len(gap_specs)} individual arrows '
|
||||||
|
f'for comparison'
|
||||||
|
)
|
||||||
|
|
||||||
|
# handle text items separately (less common, keep
|
||||||
|
# individual items)
|
||||||
|
n_texts: int = 0
|
||||||
|
for text_spec in text_specs:
|
||||||
|
kwargs: dict = text_spec.copy()
|
||||||
|
text: str = kwargs.pop('text')
|
||||||
|
x: float = float(kwargs.pop('x'))
|
||||||
|
y: float = float(kwargs.pop('y'))
|
||||||
|
time_val: float|None = kwargs.pop('time', None)
|
||||||
|
|
||||||
|
# timestamp-based index lookup
|
||||||
|
if time_val is not None:
|
||||||
|
matches = arr[arr['time'] == time_val]
|
||||||
|
if len(matches) > 0:
|
||||||
|
x = float(matches[0]['index'])
|
||||||
|
y = float(matches[0]['close'])
|
||||||
|
|
||||||
|
color = kwargs.pop('color', 'dad_blue')
|
||||||
|
anchor = kwargs.pop('anchor', (0, 1))
|
||||||
|
font_size = kwargs.pop('font_size', None)
|
||||||
|
|
||||||
|
text_item: pg.TextItem = pg.TextItem(
|
||||||
|
text,
|
||||||
|
color=hcolor(color),
|
||||||
|
anchor=anchor,
|
||||||
|
)
|
||||||
|
|
||||||
|
if font_size is None:
|
||||||
|
from ._style import get_fonts
|
||||||
|
font, font_small = get_fonts()
|
||||||
|
font_size = font_small.px_size - 1
|
||||||
|
|
||||||
|
qfont: QFont = text_item.textItem.font()
|
||||||
|
qfont.setPixelSize(font_size)
|
||||||
|
text_item.setFont(qfont)
|
||||||
|
|
||||||
|
text_item.setPos(float(x), float(y))
|
||||||
|
chart.plotItem.addItem(text_item)
|
||||||
|
|
||||||
|
text_item._abs_x = float(x)
|
||||||
|
text_item._abs_y = float(y)
|
||||||
|
|
||||||
|
aid: str = str(uuid4())
|
||||||
|
annots[aid] = text_item
|
||||||
|
aids_set.add(aid)
|
||||||
|
result['texts'].append(aid)
|
||||||
|
n_texts += 1
|
||||||
|
|
||||||
|
profiler(
|
||||||
|
f'created text annotations: {n_texts} texts'
|
||||||
|
)
|
||||||
|
profiler.finish()
|
||||||
|
|
||||||
|
await annot_req_stream.send(result)
|
||||||
|
|
||||||
case {
|
case {
|
||||||
'cmd': 'remove',
|
'cmd': 'remove',
|
||||||
'aid': int(aid)|str(aid),
|
'aid': int(aid)|str(aid),
|
||||||
|
|
@ -471,10 +828,26 @@ async def serve_rc_annots(
|
||||||
# XXX: reposition all annotations to ensure they
|
# XXX: reposition all annotations to ensure they
|
||||||
# stay aligned with viz data after reset (eg during
|
# stay aligned with viz data after reset (eg during
|
||||||
# backfill when abs-index range changes)
|
# backfill when abs-index range changes)
|
||||||
|
chart: ChartPlotWidget = {
|
||||||
|
60: ds.hist_chart,
|
||||||
|
1: ds.chart,
|
||||||
|
}[timeframe]
|
||||||
|
viz: Viz = chart.get_viz(fqme)
|
||||||
|
arr = viz.shm.array
|
||||||
|
|
||||||
n_repositioned: int = 0
|
n_repositioned: int = 0
|
||||||
for aid, annot in annots.items():
|
for aid, annot in annots.items():
|
||||||
|
# GapAnnotations batch items have .reposition()
|
||||||
|
if hasattr(annot, 'reposition'):
|
||||||
|
annot.reposition(
|
||||||
|
array=arr,
|
||||||
|
fqme=fqme,
|
||||||
|
timeframe=timeframe,
|
||||||
|
)
|
||||||
|
n_repositioned += 1
|
||||||
|
|
||||||
# arrows and text items use abs x,y coords
|
# arrows and text items use abs x,y coords
|
||||||
if (
|
elif (
|
||||||
hasattr(annot, '_abs_x')
|
hasattr(annot, '_abs_x')
|
||||||
and
|
and
|
||||||
hasattr(annot, '_abs_y')
|
hasattr(annot, '_abs_y')
|
||||||
|
|
@ -539,12 +912,21 @@ async def remote_annotate(
|
||||||
finally:
|
finally:
|
||||||
# ensure all annots for this connection are deleted
|
# ensure all annots for this connection are deleted
|
||||||
# on any final teardown
|
# on any final teardown
|
||||||
|
profiler = Profiler(
|
||||||
|
msg=f'Annotation teardown for ctx {ctx.cid}',
|
||||||
|
disabled=False,
|
||||||
|
ms_threshold=0.0,
|
||||||
|
)
|
||||||
(_ctx, aids) = _ctxs[ctx.cid]
|
(_ctx, aids) = _ctxs[ctx.cid]
|
||||||
assert _ctx is ctx
|
assert _ctx is ctx
|
||||||
|
profiler(f'got {len(aids)} aids to remove')
|
||||||
|
|
||||||
for aid in aids:
|
for aid in aids:
|
||||||
annot: QGraphicsItem = _annots[aid]
|
annot: QGraphicsItem = _annots[aid]
|
||||||
assert rm_annot(annot)
|
assert rm_annot(annot)
|
||||||
|
|
||||||
|
profiler(f'removed all {len(aids)} annotations')
|
||||||
|
|
||||||
|
|
||||||
class AnnotCtl(Struct):
|
class AnnotCtl(Struct):
|
||||||
'''
|
'''
|
||||||
|
|
@ -746,6 +1128,64 @@ class AnnotCtl(Struct):
|
||||||
)
|
)
|
||||||
return aid
|
return aid
|
||||||
|
|
||||||
|
async def add_batch(
|
||||||
|
self,
|
||||||
|
fqme: str,
|
||||||
|
timeframe: float,
|
||||||
|
rects: list[dict]|None = None,
|
||||||
|
arrows: list[dict]|None = None,
|
||||||
|
texts: list[dict]|None = None,
|
||||||
|
show_individual_arrows: bool = False,
|
||||||
|
|
||||||
|
from_acm: bool = False,
|
||||||
|
|
||||||
|
) -> dict[str, list[int]]:
|
||||||
|
'''
|
||||||
|
Batch submit multiple annotations in single IPC msg for
|
||||||
|
much faster remote annotation vs. per-annot round-trips.
|
||||||
|
|
||||||
|
Returns dict of annotation IDs:
|
||||||
|
{
|
||||||
|
'rects': [aid1, aid2, ...],
|
||||||
|
'arrows': [aid3, aid4, ...],
|
||||||
|
'texts': [aid5, aid6, ...],
|
||||||
|
}
|
||||||
|
|
||||||
|
'''
|
||||||
|
ipc: MsgStream = self._get_ipc(fqme)
|
||||||
|
with trio.fail_after(10):
|
||||||
|
await ipc.send({
|
||||||
|
'fqme': fqme,
|
||||||
|
'cmd': 'batch',
|
||||||
|
'timeframe': timeframe,
|
||||||
|
'rects': rects or [],
|
||||||
|
'arrows': arrows or [],
|
||||||
|
'texts': texts or [],
|
||||||
|
'show_individual_arrows': show_individual_arrows,
|
||||||
|
})
|
||||||
|
result: dict = await ipc.receive()
|
||||||
|
match result:
|
||||||
|
case {'error': str(msg)}:
|
||||||
|
log.error(msg)
|
||||||
|
return {
|
||||||
|
'rects': [],
|
||||||
|
'arrows': [],
|
||||||
|
'texts': [],
|
||||||
|
}
|
||||||
|
|
||||||
|
# register all AIDs with their IPC streams
|
||||||
|
for aid_list in result.values():
|
||||||
|
for aid in aid_list:
|
||||||
|
self._ipcs[aid] = ipc
|
||||||
|
if not from_acm:
|
||||||
|
self._annot_stack.push_async_callback(
|
||||||
|
partial(
|
||||||
|
self.remove,
|
||||||
|
aid,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
async def add_text(
|
async def add_text(
|
||||||
self,
|
self,
|
||||||
fqme: str,
|
fqme: str,
|
||||||
|
|
@ -881,3 +1321,14 @@ async def open_annot_ctl(
|
||||||
_annot_stack=annots_stack,
|
_annot_stack=annots_stack,
|
||||||
)
|
)
|
||||||
yield client
|
yield client
|
||||||
|
|
||||||
|
# client exited, measure teardown time
|
||||||
|
teardown_profiler = Profiler(
|
||||||
|
msg='Client AnnotCtl teardown',
|
||||||
|
disabled=False,
|
||||||
|
ms_threshold=0.0,
|
||||||
|
)
|
||||||
|
teardown_profiler('exiting annots_stack')
|
||||||
|
|
||||||
|
teardown_profiler('annots_stack exited')
|
||||||
|
teardown_profiler('exiting gather_contexts')
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ from piker.ui.qt import (
|
||||||
QStatusBar,
|
QStatusBar,
|
||||||
QScreen,
|
QScreen,
|
||||||
QCloseEvent,
|
QCloseEvent,
|
||||||
|
QSettings,
|
||||||
)
|
)
|
||||||
from ..log import get_logger
|
from ..log import get_logger
|
||||||
from ._style import _font_small, hcolor
|
from ._style import _font_small, hcolor
|
||||||
|
|
@ -181,6 +182,13 @@ class MainWindow(QMainWindow):
|
||||||
self._status_label: QLabel = None
|
self._status_label: QLabel = None
|
||||||
self._size: tuple[int, int]|None = None
|
self._size: tuple[int, int]|None = None
|
||||||
|
|
||||||
|
# restore window geometry from previous session
|
||||||
|
settings = QSettings('pikers', 'piker')
|
||||||
|
geometry = settings.value('windowGeometry')
|
||||||
|
if geometry is not None:
|
||||||
|
self.restoreGeometry(geometry)
|
||||||
|
log.debug('Restored window geometry from previous session')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mode_label(self) -> QLabel:
|
def mode_label(self) -> QLabel:
|
||||||
|
|
||||||
|
|
@ -217,6 +225,11 @@ class MainWindow(QMainWindow):
|
||||||
'''Cancel the root actor asap.
|
'''Cancel the root actor asap.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
# save window geometry for next session
|
||||||
|
settings = QSettings('pikers', 'piker')
|
||||||
|
settings.setValue('windowGeometry', self.saveGeometry())
|
||||||
|
log.debug('Saved window geometry for next session')
|
||||||
|
|
||||||
# raising KBI seems to get intercepted by by Qt so just use the system.
|
# raising KBI seems to get intercepted by by Qt so just use the system.
|
||||||
os.kill(os.getpid(), signal.SIGINT)
|
os.kill(os.getpid(), signal.SIGINT)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import uuid
|
||||||
|
|
||||||
from bidict import bidict
|
from bidict import bidict
|
||||||
import tractor
|
import tractor
|
||||||
|
from tractor.devx.pformat import ppfmt
|
||||||
import trio
|
import trio
|
||||||
|
|
||||||
from piker import config
|
from piker import config
|
||||||
|
|
@ -1207,11 +1208,10 @@ async def process_trade_msg(
|
||||||
f'\n'
|
f'\n'
|
||||||
f'=> CANCELLING ORDER DIALOG <=\n'
|
f'=> CANCELLING ORDER DIALOG <=\n'
|
||||||
|
|
||||||
# from tractor.devx.pformat import ppfmt
|
|
||||||
# !TODO LOL, wtf the msg is causing
|
# !TODO LOL, wtf the msg is causing
|
||||||
# a recursion bug!
|
# a recursion bug!
|
||||||
# -[ ] get this shit on msgspec stat!
|
# -[ ] get this shit on msgspec stat!
|
||||||
# f'{ppfmt(broker_msg)}'
|
f'{ppfmt(broker_msg)}'
|
||||||
)
|
)
|
||||||
# do all the things for a cancel:
|
# do all the things for a cancel:
|
||||||
# - drop order-msg dialog from client table
|
# - drop order-msg dialog from client table
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ from PyQt6.QtCore import (
|
||||||
QItemSelectionModel,
|
QItemSelectionModel,
|
||||||
pyqtBoundSignal,
|
pyqtBoundSignal,
|
||||||
pyqtRemoveInputHook,
|
pyqtRemoveInputHook,
|
||||||
|
QSettings,
|
||||||
)
|
)
|
||||||
|
|
||||||
align_flag: EnumType = Qt.AlignmentFlag
|
align_flag: EnumType = Qt.AlignmentFlag
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -23,7 +23,7 @@ name = "piker"
|
||||||
version = "0.1.0a0dev0"
|
version = "0.1.0a0dev0"
|
||||||
description = "trading gear for hackers"
|
description = "trading gear for hackers"
|
||||||
authors = [{ name = "Tyler Goodlet", email = "goodboy_foss@protonmail.com" }]
|
authors = [{ name = "Tyler Goodlet", email = "goodboy_foss@protonmail.com" }]
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12, <3.14"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
readme = "README.rst"
|
readme = "README.rst"
|
||||||
keywords = [
|
keywords = [
|
||||||
|
|
@ -52,7 +52,6 @@ dependencies = [
|
||||||
"bidict >=0.23.1",
|
"bidict >=0.23.1",
|
||||||
"colorama >=0.4.6, <0.5.0",
|
"colorama >=0.4.6, <0.5.0",
|
||||||
"colorlog >=6.7.0, <7.0.0",
|
"colorlog >=6.7.0, <7.0.0",
|
||||||
"ib-insync >=0.9.86, <0.10.0",
|
|
||||||
"numpy>=2.0",
|
"numpy>=2.0",
|
||||||
"polars >=0.20.6",
|
"polars >=0.20.6",
|
||||||
"polars-fuzzy-match>=0.1.5",
|
"polars-fuzzy-match>=0.1.5",
|
||||||
|
|
@ -76,6 +75,8 @@ dependencies = [
|
||||||
"numba>=0.61.0",
|
"numba>=0.61.0",
|
||||||
"pyvnc",
|
"pyvnc",
|
||||||
"exchange-calendars>=4.13.1",
|
"exchange-calendars>=4.13.1",
|
||||||
|
"ib-async>=2.1.0",
|
||||||
|
"aeventkit>=2.1.0", # XXX, imports as eventkit?
|
||||||
]
|
]
|
||||||
# ------ dependencies ------
|
# ------ dependencies ------
|
||||||
# NOTE, by default we ship only a "headless" deps set bc
|
# NOTE, by default we ship only a "headless" deps set bc
|
||||||
|
|
@ -105,7 +106,7 @@ default-groups = [
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
uis = [
|
uis = [
|
||||||
"pyqtgraph",
|
"pyqtgraph >= 0.14.0",
|
||||||
"qdarkstyle >=3.0.2, <4.0.0",
|
"qdarkstyle >=3.0.2, <4.0.0",
|
||||||
"pyqt6 >=6.7.0, <7.0.0",
|
"pyqt6 >=6.7.0, <7.0.0",
|
||||||
|
|
||||||
|
|
@ -192,9 +193,12 @@ include = ["piker"]
|
||||||
|
|
||||||
|
|
||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
pyqtgraph = { git = "https://github.com/pikers/pyqtgraph.git" }
|
|
||||||
tomlkit = { git = "https://github.com/pikers/tomlkit.git", branch ="piker_pin" }
|
tomlkit = { git = "https://github.com/pikers/tomlkit.git", branch ="piker_pin" }
|
||||||
pyvnc = { git = "https://github.com/regulad/pyvnc.git" }
|
pyvnc = { git = "https://github.com/regulad/pyvnc.git" }
|
||||||
|
# pyqtgraph = { git = "https://github.com/pyqtgraph/pyqtgraph.git", branch = 'master' }
|
||||||
|
# pyqtgraph = { path = '../pyqtgraph', editable = true }
|
||||||
|
# ?TODO, resync our fork?
|
||||||
|
# pyqtgraph = { git = "https://github.com/pikers/pyqtgraph.git" }
|
||||||
|
|
||||||
# to get fancy next-cmd/suggestion feats prior to 0.22.2 B)
|
# to get fancy next-cmd/suggestion feats prior to 0.22.2 B)
|
||||||
# https://github.com/xonsh/xonsh/pull/6037
|
# https://github.com/xonsh/xonsh/pull/6037
|
||||||
|
|
|
||||||
424
uv.lock
424
uv.lock
|
|
@ -1,13 +1,22 @@
|
||||||
version = 1
|
version = 1
|
||||||
revision = 3
|
revision = 3
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12, <3.14"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
"python_full_version >= '3.14' and sys_platform == 'win32'",
|
"sys_platform == 'win32'",
|
||||||
"python_full_version >= '3.14' and sys_platform == 'emscripten'",
|
"sys_platform == 'emscripten'",
|
||||||
"python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
"sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||||
"python_full_version < '3.14' and sys_platform == 'win32'",
|
]
|
||||||
"python_full_version < '3.14' and sys_platform == 'emscripten'",
|
|
||||||
"python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
[[package]]
|
||||||
|
name = "aeventkit"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "numpy" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/5c/8c/c08db1a1910f8d04ec6a524de522edd0bac181bdf94dbb01183f7685cd77/aeventkit-2.1.0.tar.gz", hash = "sha256:4e7d81bb0a67227121da50a23e19e5bbf13eded541a9f4857eeb6b7b857b738a", size = 24703, upload-time = "2025-06-22T15:54:03.961Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8d/8c/2a4b912b1afa201b25bdd0f5bccf96d5a8b5dccb6131316a8dd2d9cabcc1/aeventkit-2.1.0-py3-none-any.whl", hash = "sha256:962d43f79e731ac43527f2d0defeed118e6dbaa85f1487f5667540ebb8f00729", size = 26678, upload-time = "2025-06-22T15:54:02.141Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -173,28 +182,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
|
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
|
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -235,22 +222,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
|
{ url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
|
{ url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
|
{ url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
|
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -353,10 +324,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/21/a8038c8253e7a5241ed1db6d031bac586f7a502d92f487124abbc3f3e94f/cython-3.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60f4aa425e1ff98abf8d965ae7020f06dd2cbc01dbd945137d2f9cca4ff0524a", size = 3212479, upload-time = "2025-11-30T12:48:57.567Z" },
|
{ url = "https://files.pythonhosted.org/packages/46/21/a8038c8253e7a5241ed1db6d031bac586f7a502d92f487124abbc3f3e94f/cython-3.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60f4aa425e1ff98abf8d965ae7020f06dd2cbc01dbd945137d2f9cca4ff0524a", size = 3212479, upload-time = "2025-11-30T12:48:57.567Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/57/c1/76928c07176a4402c74d5b304936ad8ee167dd04a07cf7dca545e8c25f9b/cython-3.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a473df474ba89e9fee81ee82b31062a267f9e598096b222783477e56d02ad12c", size = 3374773, upload-time = "2025-11-30T12:48:59.318Z" },
|
{ url = "https://files.pythonhosted.org/packages/57/c1/76928c07176a4402c74d5b304936ad8ee167dd04a07cf7dca545e8c25f9b/cython-3.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a473df474ba89e9fee81ee82b31062a267f9e598096b222783477e56d02ad12c", size = 3374773, upload-time = "2025-11-30T12:48:59.318Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fa/cb/ce641e07ba9c0cde8468e83e0214fb87020b74ba34dbb9dfe8d250a327f5/cython-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:b4df52101209817fde7284cf779156f79142fb639b1d7840f11680ff4bb30604", size = 2754492, upload-time = "2025-11-30T12:49:01.029Z" },
|
{ url = "https://files.pythonhosted.org/packages/fa/cb/ce641e07ba9c0cde8468e83e0214fb87020b74ba34dbb9dfe8d250a327f5/cython-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:b4df52101209817fde7284cf779156f79142fb639b1d7840f11680ff4bb30604", size = 2754492, upload-time = "2025-11-30T12:49:01.029Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c0/f2/cd60f639f0fde38b71319d7b6808e1ff17a6fd7f3feaff475b866a5c0aef/cython-3.2.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:177faf4d61e9f2d4d2db61194ac9ec16d3fe3041c1b6830f871a01935319eeb3", size = 2969023, upload-time = "2025-11-30T12:49:02.734Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5d/45/6f155a9ad125536d8f30716c4d7571caae73ec811039d3ae33f9b535090d/cython-3.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8db28aef793c81dc69383b619ca508668998aaf099cd839d3cbae85184cce744", size = 3258270, upload-time = "2025-11-30T12:49:04.878Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/7e/022c25886fdc3ff6a005b6ae4a1c3d8522006bb738367aa5bd6c2590130b/cython-3.2.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3de43a5786033a27fae1c882feb5ff0d023c38b83356e6800c1be0bcd6cf9f11", size = 3384504, upload-time = "2025-11-30T12:49:07.078Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b6/07/1e3e4faf6f785d5ba053e9d6320b3f338162dc122c27a7c540b49615fc39/cython-3.2.2-cp314-cp314-win_amd64.whl", hash = "sha256:fed44d0ab2d36f1b0301c770b0dafec23bcb9700d58e7769cd6d9136b3304c11", size = 2791504, upload-time = "2025-11-30T12:49:08.729Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f4/69/5430879d35235ec3d5ffd778862173b6419390509ae4e37a72bdd45d9e86/cython-3.2.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a6387e3ad31342443916db9a419509935fddd8d4cbac34aab9c895ae55326a56", size = 2874031, upload-time = "2025-11-30T12:49:18.34Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/69/5430879d35235ec3d5ffd778862173b6419390509ae4e37a72bdd45d9e86/cython-3.2.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a6387e3ad31342443916db9a419509935fddd8d4cbac34aab9c895ae55326a56", size = 2874031, upload-time = "2025-11-30T12:49:18.34Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/51/fa/584f4b56b35b3e7a43dc16603dd722cb5528484da67c27136534b782827b/cython-3.2.2-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:436eb562d0affbc0b959f62f3f9c1ed251b9499e4f29c1d19514ae859894b6bf", size = 3210813, upload-time = "2025-11-30T12:49:20.55Z" },
|
{ url = "https://files.pythonhosted.org/packages/51/fa/584f4b56b35b3e7a43dc16603dd722cb5528484da67c27136534b782827b/cython-3.2.2-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:436eb562d0affbc0b959f62f3f9c1ed251b9499e4f29c1d19514ae859894b6bf", size = 3210813, upload-time = "2025-11-30T12:49:20.55Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d1/d4/063c34a34d9ef54836a5dafb100b8f4fdbdaa63942913fe93f9eb93a11a2/cython-3.2.2-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f560ff3aea5b5df93853ec7bf1a1e9623d6d511f4192f197559aca18fca43392", size = 2855611, upload-time = "2025-11-30T12:49:22.303Z" },
|
{ url = "https://files.pythonhosted.org/packages/d1/d4/063c34a34d9ef54836a5dafb100b8f4fdbdaa63942913fe93f9eb93a11a2/cython-3.2.2-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f560ff3aea5b5df93853ec7bf1a1e9623d6d511f4192f197559aca18fca43392", size = 2855611, upload-time = "2025-11-30T12:49:22.303Z" },
|
||||||
|
|
@ -396,18 +363,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/56/01/6f77d042b83260ef9ed73ea9647dfa0ef8414eba0a3fc57a509a088ad39b/elasticsearch-8.19.2-py3-none-any.whl", hash = "sha256:c16ba20c4c76cf6952e836dae7f4e724e00ba7bf31b94b79472b873683accdd4", size = 949706, upload-time = "2025-10-28T16:36:41.003Z" },
|
{ url = "https://files.pythonhosted.org/packages/56/01/6f77d042b83260ef9ed73ea9647dfa0ef8414eba0a3fc57a509a088ad39b/elasticsearch-8.19.2-py3-none-any.whl", hash = "sha256:c16ba20c4c76cf6952e836dae7f4e724e00ba7bf31b94b79472b873683accdd4", size = 949706, upload-time = "2025-10-28T16:36:41.003Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "eventkit"
|
|
||||||
version = "1.0.3"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "numpy" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/16/1e/0fac4e45d71ace143a2673ec642701c3cd16f833a0e77a57fa6a40472696/eventkit-1.0.3.tar.gz", hash = "sha256:99497f6f3c638a50ff7616f2f8cd887b18bbff3765dc1bd8681554db1467c933", size = 28320, upload-time = "2023-12-11T11:41:35.339Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/93/d9/7497d650b69b420e1a913329a843e16c715dac883750679240ef00a921e2/eventkit-1.0.3-py3-none-any.whl", hash = "sha256:0e199527a89aff9d195b9671ad45d2cc9f79ecda0900de8ecfb4c864d67ad6a2", size = 31837, upload-time = "2023-12-11T11:41:33.358Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exceptiongroup"
|
name = "exceptiongroup"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
|
@ -491,38 +446,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" },
|
{ url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" },
|
{ url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" },
|
{ url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" },
|
{ url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -562,21 +485,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" },
|
{ url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" },
|
{ url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -630,16 +538,17 @@ wheels = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ib-insync"
|
name = "ib-async"
|
||||||
version = "0.9.86"
|
version = "2.1.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "eventkit" },
|
{ name = "aeventkit" },
|
||||||
{ name = "nest-asyncio" },
|
{ name = "nest-asyncio" },
|
||||||
|
{ name = "tzdata" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/55/bb/733d5c81c8c2f54e90898afc7ff3a99f4d53619e6917c848833f9cc1ab56/ib_insync-0.9.86.tar.gz", hash = "sha256:73af602ca2463f260999970c5bd937b1c4325e383686eff301743a4de08d381e", size = 69859, upload-time = "2023-07-02T12:43:31.968Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/30/4d/dfc1da8224c3ffcdcd668da7283c4e5f14239a07f83ea66af99700296fc3/ib_async-2.1.0.tar.gz", hash = "sha256:6a03a87d6c06acacb0217a5bea60a8a168ecd5b5a7e86e1c73678d5b48cbc796", size = 87678, upload-time = "2025-12-08T01:42:32.004Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/8f/f3/28ea87be30570f4d6b8fd24380d12fa74e59467ee003755e76aeb29082b8/ib_insync-0.9.86-py3-none-any.whl", hash = "sha256:a61fbe56ff405d93d211dad8238d7300de76dd6399eafc04c320470edec9a4a4", size = 72980, upload-time = "2023-07-02T12:43:29.928Z" },
|
{ url = "https://files.pythonhosted.org/packages/80/e7/8f33801788c66f15e9250957ff7f53a8000843f79af1a3ed7a96def0e96b/ib_async-2.1.0-py3-none-any.whl", hash = "sha256:f6d8b991bdbd6dd38e700c61b3dced06ebe0f14be4e5263e2ef10ba10b88d434", size = 88876, upload-time = "2025-12-08T01:42:30.883Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -810,42 +719,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" },
|
{ url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" },
|
{ url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" },
|
{ url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" },
|
{ url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -928,28 +801,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" },
|
{ url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" },
|
{ url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" },
|
{ url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1017,22 +868,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/55/db/2570bc40fb13aaed1cbc3fbd725c3a60ee162477982123c3adc8971e7ac1/pandas-3.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66f72fb172959af42a459e27a8d8d2c7e311ff4c1f7db6deb3b643dbc382ae08", size = 11323737, upload-time = "2026-01-21T15:51:20.784Z" },
|
{ url = "https://files.pythonhosted.org/packages/55/db/2570bc40fb13aaed1cbc3fbd725c3a60ee162477982123c3adc8971e7ac1/pandas-3.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66f72fb172959af42a459e27a8d8d2c7e311ff4c1f7db6deb3b643dbc382ae08", size = 11323737, upload-time = "2026-01-21T15:51:20.784Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bc/2e/297ac7f21c8181b62a4cccebad0a70caf679adf3ae5e83cb676194c8acc3/pandas-3.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a4a400ca18230976724a5066f20878af785f36c6756e498e94c2a5e5d57779c", size = 11771558, upload-time = "2026-01-21T15:51:22.977Z" },
|
{ url = "https://files.pythonhosted.org/packages/bc/2e/297ac7f21c8181b62a4cccebad0a70caf679adf3ae5e83cb676194c8acc3/pandas-3.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a4a400ca18230976724a5066f20878af785f36c6756e498e94c2a5e5d57779c", size = 11771558, upload-time = "2026-01-21T15:51:22.977Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0a/46/e1c6876d71c14332be70239acce9ad435975a80541086e5ffba2f249bcf6/pandas-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:940eebffe55528074341a5a36515f3e4c5e25e958ebbc764c9502cfc35ba3faa", size = 10473771, upload-time = "2026-01-21T15:51:25.285Z" },
|
{ url = "https://files.pythonhosted.org/packages/0a/46/e1c6876d71c14332be70239acce9ad435975a80541086e5ffba2f249bcf6/pandas-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:940eebffe55528074341a5a36515f3e4c5e25e958ebbc764c9502cfc35ba3faa", size = 10473771, upload-time = "2026-01-21T15:51:25.285Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c0/db/0270ad9d13c344b7a36fa77f5f8344a46501abf413803e885d22864d10bf/pandas-3.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:597c08fb9fef0edf1e4fa2f9828dd27f3d78f9b8c9b4a748d435ffc55732310b", size = 10312075, upload-time = "2026-01-21T15:51:28.5Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/09/9f/c176f5e9717f7c91becfe0f55a52ae445d3f7326b4a2cf355978c51b7913/pandas-3.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:447b2d68ac5edcbf94655fe909113a6dba6ef09ad7f9f60c80477825b6c489fe", size = 9900213, upload-time = "2026-01-21T15:51:30.955Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d9/e7/63ad4cc10b257b143e0a5ebb04304ad806b4e1a61c5da25f55896d2ca0f4/pandas-3.0.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:debb95c77ff3ed3ba0d9aa20c3a2f19165cc7956362f9873fce1ba0a53819d70", size = 10428768, upload-time = "2026-01-21T15:51:33.018Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/0e/4e4c2d8210f20149fd2248ef3fff26623604922bd564d915f935a06dd63d/pandas-3.0.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fedabf175e7cd82b69b74c30adbaa616de301291a5231138d7242596fc296a8d", size = 10882954, upload-time = "2026-01-21T15:51:35.287Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c6/60/c9de8ac906ba1f4d2250f8a951abe5135b404227a55858a75ad26f84db47/pandas-3.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:412d1a89aab46889f3033a386912efcdfa0f1131c5705ff5b668dda88305e986", size = 11430293, upload-time = "2026-01-21T15:51:37.57Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/69/806e6637c70920e5787a6d6896fd707f8134c2c55cd761e7249a97b7dc5a/pandas-3.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e979d22316f9350c516479dd3a92252be2937a9531ed3a26ec324198a99cdd49", size = 11952452, upload-time = "2026-01-21T15:51:39.618Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/de/918621e46af55164c400ab0ef389c9d969ab85a43d59ad1207d4ddbe30a5/pandas-3.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:083b11415b9970b6e7888800c43c82e81a06cd6b06755d84804444f0007d6bb7", size = 9851081, upload-time = "2026-01-21T15:51:41.758Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/91/a1/3562a18dd0bd8c73344bfa26ff90c53c72f827df119d6d6b1dacc84d13e3/pandas-3.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:5db1e62cb99e739fa78a28047e861b256d17f88463c76b8dafc7c1338086dca8", size = 9174610, upload-time = "2026-01-21T15:51:44.312Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/26/430d91257eaf366f1737d7a1c158677caaf6267f338ec74e3a1ec444111c/pandas-3.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:697b8f7d346c68274b1b93a170a70974cdc7d7354429894d5927c1effdcccd73", size = 10761999, upload-time = "2026-01-21T15:51:46.899Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/1a/954eb47736c2b7f7fe6a9d56b0cb6987773c00faa3c6451a43db4beb3254/pandas-3.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8cb3120f0d9467ed95e77f67a75e030b67545bcfa08964e349252d674171def2", size = 10410279, upload-time = "2026-01-21T15:51:48.89Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/20/fc/b96f3a5a28b250cd1b366eb0108df2501c0f38314a00847242abab71bb3a/pandas-3.0.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33fd3e6baa72899746b820c31e4b9688c8e1b7864d7aec2de7ab5035c285277a", size = 10330198, upload-time = "2026-01-21T15:51:51.015Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/90/b3/d0e2952f103b4fbef1ef22d0c2e314e74fc9064b51cee30890b5e3286ee6/pandas-3.0.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8942e333dc67ceda1095227ad0febb05a3b36535e520154085db632c40ad084", size = 10728513, upload-time = "2026-01-21T15:51:53.387Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/76/81/832894f286df828993dc5fd61c63b231b0fb73377e99f6c6c369174cf97e/pandas-3.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:783ac35c4d0fe0effdb0d67161859078618b1b6587a1af15928137525217a721", size = 11345550, upload-time = "2026-01-21T15:51:55.329Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/34/a0/ed160a00fb4f37d806406bc0a79a8b62fe67f29d00950f8d16203ff3409b/pandas-3.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:125eb901e233f155b268bbef9abd9afb5819db74f0e677e89a61b246228c71ac", size = 11799386, upload-time = "2026-01-21T15:51:57.457Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/36/c8/2ac00d7255252c5e3cf61b35ca92ca25704b0188f7454ca4aec08a33cece/pandas-3.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b86d113b6c109df3ce0ad5abbc259fe86a1bd4adfd4a31a89da42f84f65509bb", size = 10873041, upload-time = "2026-01-21T15:52:00.034Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e6/3f/a80ac00acbc6b35166b42850e98a4f466e2c0d9c64054161ba9620f95680/pandas-3.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1c39eab3ad38f2d7a249095f0a3d8f8c22cc0f847e98ccf5bbe732b272e2d9fa", size = 9441003, upload-time = "2026-01-21T15:52:02.281Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1099,6 +934,7 @@ name = "piker"
|
||||||
version = "0.1.0a0.dev0"
|
version = "0.1.0a0.dev0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
{ name = "aeventkit" },
|
||||||
{ name = "async-generator" },
|
{ name = "async-generator" },
|
||||||
{ name = "attrs" },
|
{ name = "attrs" },
|
||||||
{ name = "bidict" },
|
{ name = "bidict" },
|
||||||
|
|
@ -1107,7 +943,7 @@ dependencies = [
|
||||||
{ name = "cryptofeed" },
|
{ name = "cryptofeed" },
|
||||||
{ name = "exchange-calendars" },
|
{ name = "exchange-calendars" },
|
||||||
{ name = "httpx" },
|
{ name = "httpx" },
|
||||||
{ name = "ib-insync" },
|
{ name = "ib-async" },
|
||||||
{ name = "msgspec" },
|
{ name = "msgspec" },
|
||||||
{ name = "numba" },
|
{ name = "numba" },
|
||||||
{ name = "numpy" },
|
{ name = "numpy" },
|
||||||
|
|
@ -1175,6 +1011,7 @@ uis = [
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
|
{ name = "aeventkit", specifier = ">=2.1.0" },
|
||||||
{ name = "async-generator", specifier = ">=1.10,<2.0.0" },
|
{ name = "async-generator", specifier = ">=1.10,<2.0.0" },
|
||||||
{ name = "attrs", specifier = ">=23.1.0,<24.0.0" },
|
{ name = "attrs", specifier = ">=23.1.0,<24.0.0" },
|
||||||
{ name = "bidict", specifier = ">=0.23.1" },
|
{ name = "bidict", specifier = ">=0.23.1" },
|
||||||
|
|
@ -1183,7 +1020,7 @@ requires-dist = [
|
||||||
{ name = "cryptofeed", specifier = ">=2.4.0,<3.0.0" },
|
{ name = "cryptofeed", specifier = ">=2.4.0,<3.0.0" },
|
||||||
{ name = "exchange-calendars", specifier = ">=4.13.1" },
|
{ name = "exchange-calendars", specifier = ">=4.13.1" },
|
||||||
{ name = "httpx", specifier = ">=0.27.0,<0.28.0" },
|
{ name = "httpx", specifier = ">=0.27.0,<0.28.0" },
|
||||||
{ name = "ib-insync", specifier = ">=0.9.86,<0.10.0" },
|
{ name = "ib-async", specifier = ">=2.1.0" },
|
||||||
{ name = "msgspec", specifier = ">=0.19.0,<0.20" },
|
{ name = "msgspec", specifier = ">=0.19.0,<0.20" },
|
||||||
{ name = "numba", specifier = ">=0.61.0" },
|
{ name = "numba", specifier = ">=0.61.0" },
|
||||||
{ name = "numpy", specifier = ">=2.0" },
|
{ name = "numpy", specifier = ">=2.0" },
|
||||||
|
|
@ -1218,7 +1055,7 @@ dev = [
|
||||||
{ name = "prompt-toolkit", specifier = "==3.0.40" },
|
{ name = "prompt-toolkit", specifier = "==3.0.40" },
|
||||||
{ name = "pyperclip", specifier = ">=1.9.0" },
|
{ name = "pyperclip", specifier = ">=1.9.0" },
|
||||||
{ name = "pyqt6", specifier = ">=6.7.0,<7.0.0" },
|
{ name = "pyqt6", specifier = ">=6.7.0,<7.0.0" },
|
||||||
{ name = "pyqtgraph", git = "https://github.com/pikers/pyqtgraph.git" },
|
{ name = "pyqtgraph", specifier = ">=0.14.0" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "qdarkstyle", specifier = ">=3.0.2,<4.0.0" },
|
{ name = "qdarkstyle", specifier = ">=3.0.2,<4.0.0" },
|
||||||
{ name = "rapidfuzz", specifier = ">=3.2.0,<4.0.0" },
|
{ name = "rapidfuzz", specifier = ">=3.2.0,<4.0.0" },
|
||||||
|
|
@ -1236,7 +1073,7 @@ repl = [
|
||||||
testing = [{ name = "pytest" }]
|
testing = [{ name = "pytest" }]
|
||||||
uis = [
|
uis = [
|
||||||
{ name = "pyqt6", specifier = ">=6.7.0,<7.0.0" },
|
{ name = "pyqt6", specifier = ">=6.7.0,<7.0.0" },
|
||||||
{ name = "pyqtgraph", git = "https://github.com/pikers/pyqtgraph.git" },
|
{ name = "pyqtgraph", specifier = ">=0.14.0" },
|
||||||
{ name = "qdarkstyle", specifier = ">=3.0.2,<4.0.0" },
|
{ name = "qdarkstyle", specifier = ">=3.0.2,<4.0.0" },
|
||||||
{ name = "rapidfuzz", specifier = ">=3.2.0,<4.0.0" },
|
{ name = "rapidfuzz", specifier = ">=3.2.0,<4.0.0" },
|
||||||
]
|
]
|
||||||
|
|
@ -1364,36 +1201,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" },
|
{ url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" },
|
{ url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" },
|
{ url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" },
|
{ url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1433,20 +1240,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload-time = "2025-10-24T10:07:43.528Z" },
|
{ url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload-time = "2025-10-24T10:07:43.528Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload-time = "2025-10-24T10:07:53.519Z" },
|
{ url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload-time = "2025-10-24T10:07:53.519Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload-time = "2025-10-24T10:08:00.932Z" },
|
{ url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload-time = "2025-10-24T10:08:00.932Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062, upload-time = "2025-10-24T10:08:14.101Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057, upload-time = "2025-10-24T10:08:21.842Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002, upload-time = "2025-10-24T10:08:29.034Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765, upload-time = "2025-10-24T10:08:38.559Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139, upload-time = "2025-10-24T10:08:46.784Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244, upload-time = "2025-10-24T10:08:55.771Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501, upload-time = "2025-10-24T10:09:59.891Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506, upload-time = "2025-10-24T10:09:02.953Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312, upload-time = "2025-10-24T10:09:10.334Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609, upload-time = "2025-10-24T10:09:18.61Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663, upload-time = "2025-10-24T10:09:27.369Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543, upload-time = "2025-10-24T10:09:34.908Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838, upload-time = "2025-10-24T10:09:44.394Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1484,32 +1277,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/99/60f19eb1c8eb898882dd8875ea51ad0aac3aff5780b27247969e637cc26a/pycares-4.11.0-cp313-cp313-win32.whl", hash = "sha256:faa8321bc2a366189dcf87b3823e030edf5ac97a6b9a7fc99f1926c4bf8ef28e", size = 118918, upload-time = "2025-09-09T15:17:23.327Z" },
|
{ url = "https://files.pythonhosted.org/packages/05/99/60f19eb1c8eb898882dd8875ea51ad0aac3aff5780b27247969e637cc26a/pycares-4.11.0-cp313-cp313-win32.whl", hash = "sha256:faa8321bc2a366189dcf87b3823e030edf5ac97a6b9a7fc99f1926c4bf8ef28e", size = 118918, upload-time = "2025-09-09T15:17:23.327Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/14/bc89ad7225cba73068688397de09d7cad657d67b93641c14e5e18b88e685/pycares-4.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:6f74b1d944a50fa12c5006fd10b45e1a45da0c5d15570919ce48be88e428264c", size = 144556, upload-time = "2025-09-09T15:17:24.341Z" },
|
{ url = "https://files.pythonhosted.org/packages/2a/14/bc89ad7225cba73068688397de09d7cad657d67b93641c14e5e18b88e685/pycares-4.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:6f74b1d944a50fa12c5006fd10b45e1a45da0c5d15570919ce48be88e428264c", size = 144556, upload-time = "2025-09-09T15:17:24.341Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/88/4309576bd74b5e6fc1f39b9bc5e4b578df2cadb16bdc026ac0cc15663763/pycares-4.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f7581793d8bb3014028b8397f6f80b99db8842da58f4409839c29b16397ad", size = 115692, upload-time = "2025-09-09T15:17:25.637Z" },
|
{ url = "https://files.pythonhosted.org/packages/af/88/4309576bd74b5e6fc1f39b9bc5e4b578df2cadb16bdc026ac0cc15663763/pycares-4.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f7581793d8bb3014028b8397f6f80b99db8842da58f4409839c29b16397ad", size = 115692, upload-time = "2025-09-09T15:17:25.637Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/70/a723bc79bdcac60361b40184b649282ac0ab433b90e9cc0975370c2ff9c9/pycares-4.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:df0a17f4e677d57bca3624752bbb515316522ad1ce0de07ed9d920e6c4ee5d35", size = 145910, upload-time = "2025-09-09T15:17:26.774Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d5/4e/46311ef5a384b5f0bb206851135dde8f86b3def38fdbee9e3c03475d35ae/pycares-4.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3b44e54cad31d3c3be5e8149ac36bc1c163ec86e0664293402f6f846fb22ad00", size = 142053, upload-time = "2025-09-09T15:17:27.956Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/74/23/d236fc4f134d6311e4ad6445571e8285e84a3e155be36422ff20c0fbe471/pycares-4.11.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:80752133442dc7e6dd9410cec227c49f69283c038c316a8585cca05ec32c2766", size = 637878, upload-time = "2025-09-09T15:17:29.173Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f7/92/6edd41282b3f0e3d9defaba7b05c39730d51c37c165d9d3b319349c975aa/pycares-4.11.0-cp314-cp314-manylinux_2_28_ppc64le.whl", hash = "sha256:84b0b402dd333403fdce0e204aef1ef834d839c439c0c1aa143dc7d1237bb197", size = 687865, upload-time = "2025-09-09T15:17:30.549Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a7/a9/4d7cf4d72600fd47d9518f9ce99703a3e8711fb08d2ef63d198056cdc9a9/pycares-4.11.0-cp314-cp314-manylinux_2_28_s390x.whl", hash = "sha256:c0eec184df42fc82e43197e073f9cc8f93b25ad2f11f230c64c2dc1c80dbc078", size = 678396, upload-time = "2025-09-09T15:17:32.304Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/4b/e546eeb1d8ff6559e2e3bef31a6ea0c6e57ec826191941f83a3ce900ca89/pycares-4.11.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ee751409322ff10709ee867d5aea1dc8431eec7f34835f0f67afd016178da134", size = 640786, upload-time = "2025-09-09T15:17:33.602Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/f5/b4572d9ee9c26de1f8d1dc80730df756276b9243a6794fa3101bbe56613d/pycares-4.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1732db81e348bfce19c9bf9448ba660aea03042eeeea282824da1604a5bd4dcf", size = 621857, upload-time = "2025-09-09T15:17:34.74Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/17/f2/639090376198bcaeff86562b25e1bce05a481cfb1e605f82ce62285230cd/pycares-4.11.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:702d21823996f139874aba5aa9bb786d69e93bde6e3915b99832eb4e335d31ae", size = 670130, upload-time = "2025-09-09T15:17:35.982Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/c4/cf40773cd9c36a12cebbe1e9b6fb120f9160dc9bfe0398d81a20b6c69972/pycares-4.11.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:218619b912cef7c64a339ab0e231daea10c994a05699740714dff8c428b9694a", size = 653133, upload-time = "2025-09-09T15:17:37.179Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/32/6b/06054d977b0a9643821043b59f523f3db5e7684c4b1b4f5821994d5fa780/pycares-4.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:719f7ddff024fdacde97b926b4b26d0cc25901d5ef68bb994a581c420069936d", size = 629344, upload-time = "2025-09-09T15:17:38.308Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d6/6f/14bb0c2171a286d512e3f02d6168e608ffe5f6eceab78bf63e3073091ae3/pycares-4.11.0-cp314-cp314-win32.whl", hash = "sha256:d552fb2cb513ce910d1dc22dbba6420758a991a356f3cd1b7ec73a9e31f94d01", size = 121804, upload-time = "2025-09-09T15:17:39.388Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/24/dc/6822f9ad6941027f70e1cf161d8631456531a87061588ed3b1dcad07d49d/pycares-4.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:23d50a0842e8dbdddf870a7218a7ab5053b68892706b3a391ecb3d657424d266", size = 148005, upload-time = "2025-09-09T15:17:40.44Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ea/24/24ff3a80aa8471fbb62785c821a8e90f397ca842e0489f83ebf7ee274397/pycares-4.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:836725754c32363d2c5d15b931b3ebd46b20185c02e850672cb6c5f0452c1e80", size = 119239, upload-time = "2025-09-09T15:17:42.094Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/54/fe/2f3558d298ff8db31d5c83369001ab72af3b86a0374d9b0d40dc63314187/pycares-4.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c9d839b5700542b27c1a0d359cbfad6496341e7c819c7fea63db9588857065ed", size = 146408, upload-time = "2025-09-09T15:17:43.74Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/c8/516901e46a1a73b3a75e87a35f3a3a4fe085f1214f37d954c9d7e782bd6d/pycares-4.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:31b85ad00422b38f426e5733a71dfb7ee7eb65a99ea328c508d4f552b1760dc8", size = 142371, upload-time = "2025-09-09T15:17:45.186Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ac/99/c3fba0aa575f331ebed91f87ba960ffbe0849211cdf103ab275bc0107ac6/pycares-4.11.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:cdac992206756b024b371760c55719eb5cd9d6b2cb25a8d5a04ae1b0ff426232", size = 647504, upload-time = "2025-09-09T15:17:46.503Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/e4/1cdc3ec9c92f8069ec18c58b016b2df7c44a088e2849f37ed457554961aa/pycares-4.11.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:ffb22cee640bc12ee0e654eba74ecfb59e2e0aebc5bccc3cc7ef92f487008af7", size = 697122, upload-time = "2025-09-09T15:17:47.772Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9c/d5/bd8f370b97bb73e5bdd55dc2a78e18d6f49181cf77e88af0599d16f5c073/pycares-4.11.0-cp314-cp314t-manylinux_2_28_s390x.whl", hash = "sha256:00538826d2eaf4a0e4becb0753b0ac8d652334603c445c9566c9eb273657eb4c", size = 687543, upload-time = "2025-09-09T15:17:49.183Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/33/38/49b77b9cf5dffc0b1fdd86656975c3bc1a58b79bdc883a9ef749b17a013c/pycares-4.11.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:29daa36548c04cdcd1a78ae187a4b7b003f0b357a2f4f1f98f9863373eedc759", size = 649565, upload-time = "2025-09-09T15:17:51.03Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/23/f6d57bfb99d00a6a7363f95c8d3a930fe82a868d9de24c64c8048d66f16a/pycares-4.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:cf306f3951740d7bed36149a6d8d656a7d5432dd4bbc6af3bb6554361fc87401", size = 631242, upload-time = "2025-09-09T15:17:52.298Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/33/a2/7b9121c71cfe06a8474e221593f83a78176fae3b79e5853d2dfd13ab01cc/pycares-4.11.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:386da2581db4ea2832629e275c061103b0be32f9391c5dfaea7f6040951950ad", size = 680304, upload-time = "2025-09-09T15:17:53.638Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/07/dfe76807f637d8b80e1a59dfc4a1bceabdd0205a45b2ebf78b415ae72af3/pycares-4.11.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:45d3254a694459fdb0640ef08724ca9d4b4f6ff6d7161c9b526d7d2e2111379e", size = 661039, upload-time = "2025-09-09T15:17:55.024Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/9b/55d50c5acd46cbe95d0da27740a83e721d89c0ce7e42bff9891a9f29a855/pycares-4.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eddf5e520bb88b23b04ac1f28f5e9a7c77c718b8b4af3a4a7a2cc4a600f34502", size = 637560, upload-time = "2025-09-09T15:17:56.492Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1f/79/2b2e723d1b929dbe7f99e80a56abb29a4f86988c1f73195d960d706b1629/pycares-4.11.0-cp314-cp314t-win32.whl", hash = "sha256:8a75a406432ce39ce0ca41edff7486df6c970eb0fe5cfbe292f195a6b8654461", size = 122235, upload-time = "2025-09-09T15:17:57.576Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/93/fe/bf3b3ed9345a38092e72cd9890a5df5c2349fc27846a714d823a41f0ee27/pycares-4.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3784b80d797bcc2ff2bf3d4b27f46d8516fe1707ff3b82c2580dc977537387f9", size = 148575, upload-time = "2025-09-09T15:17:58.699Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/20/c0c5cfcf89725fe533b27bc5f714dc4efa8e782bf697c36f9ddf04ba975d/pycares-4.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:afc6503adf8b35c21183b9387be64ca6810644ef54c9ef6c99d1d5635c01601b", size = 119690, upload-time = "2025-09-09T15:17:59.809Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1594,20 +1361,19 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/8d/a2eaccc88cc53e6370e3728593ea80d10a132f87078ce7cbcfc8c33d9b3f/pyqt6_sip-13.10.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e234a3af9539f71bb566e7136317b92f189a89553970284d833cd63cca4dafdd", size = 323466, upload-time = "2025-12-06T13:19:34.445Z" },
|
{ url = "https://files.pythonhosted.org/packages/cd/8d/a2eaccc88cc53e6370e3728593ea80d10a132f87078ce7cbcfc8c33d9b3f/pyqt6_sip-13.10.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e234a3af9539f71bb566e7136317b92f189a89553970284d833cd63cca4dafdd", size = 323466, upload-time = "2025-12-06T13:19:34.445Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/f8/55a93c3eda94c94fc10c2537f55ca98d9bb1982bf65c03ee2302c250b6aa/pyqt6_sip-13.10.3-cp313-cp313-win_amd64.whl", hash = "sha256:a856b9b2a4700c8dded1c870811d5ba26722238d57c9098904a99570429d112b", size = 53468, upload-time = "2025-12-06T13:19:36.877Z" },
|
{ url = "https://files.pythonhosted.org/packages/47/f8/55a93c3eda94c94fc10c2537f55ca98d9bb1982bf65c03ee2302c250b6aa/pyqt6_sip-13.10.3-cp313-cp313-win_amd64.whl", hash = "sha256:a856b9b2a4700c8dded1c870811d5ba26722238d57c9098904a99570429d112b", size = 53468, upload-time = "2025-12-06T13:19:36.877Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/41/a3/ee0633507350442580a2cd893e4edb7170d87fef1c790365e7bc4999ce40/pyqt6_sip-13.10.3-cp313-cp313-win_arm64.whl", hash = "sha256:9e48e5d6ac9e1a61d5abdfb2191a0ffb19948eefd5adacdd0c1dedbed06222aa", size = 48645, upload-time = "2025-12-06T13:19:38.216Z" },
|
{ url = "https://files.pythonhosted.org/packages/41/a3/ee0633507350442580a2cd893e4edb7170d87fef1c790365e7bc4999ce40/pyqt6_sip-13.10.3-cp313-cp313-win_arm64.whl", hash = "sha256:9e48e5d6ac9e1a61d5abdfb2191a0ffb19948eefd5adacdd0c1dedbed06222aa", size = 48645, upload-time = "2025-12-06T13:19:38.216Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/70/a22362c2632d07d8e29431418e0485f12a41b3c4844f15b60ca5a969e01c/pyqt6_sip-13.10.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:eb7afe41329ce2eca99118f01776a047a2a150c550258dff1746505af223f997", size = 112432, upload-time = "2025-12-06T13:19:39.153Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/25/72/e0a7e4489ea5b948aef707a7d76baf6722a65aabd7e4d3c253583eb6b268/pyqt6_sip-13.10.3-cp314-cp314-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6122fe4ccba5a5023581c2c3c57deab6eab56d8e931beec20b05666a46a38e6a", size = 301341, upload-time = "2025-12-06T13:19:41.642Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1f/43/0a648469a7e4f07df1c4ad6443f892e55631f24f7af30c7c946e458a82d1/pyqt6_sip-13.10.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3286a98e93608d51048e9046f557117424c8366be266b33ff852ee54ffa7b9bf", size = 324062, upload-time = "2025-12-06T13:19:40.308Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f3/0d/67d2095a932c007210437318c31fbc8376deb4e4491907861c4b9ac4ad9e/pyqt6_sip-13.10.3-cp314-cp314-win_amd64.whl", hash = "sha256:4fc6229ba7276266e3805b5517e7413cba79538f0c3ce7d2042a2027a90f99cf", size = 55076, upload-time = "2025-12-06T13:19:42.61Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f8/cd/f121be0271dc73d54f3580584103c046a8d2c06a2686b594b77fd677a5ef/pyqt6_sip-13.10.3-cp314-cp314-win_arm64.whl", hash = "sha256:efef47667ca009557d7ecf985b15f0bf440584fd634ee0eab19ec296effc7cca", size = 49464, upload-time = "2025-12-06T13:19:43.638Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyqtgraph"
|
name = "pyqtgraph"
|
||||||
version = "0.12.3"
|
version = "0.14.0"
|
||||||
source = { git = "https://github.com/pikers/pyqtgraph.git#373f9561ea8ec4fef9b4e8bdcdd4bbf372dd6512" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
{ name = "colorama" },
|
||||||
{ name = "numpy" },
|
{ name = "numpy" },
|
||||||
]
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/32/36/4c242f81fdcbfa4fb62a5645f6af79191f4097a0577bd5460c24f19cc4ef/pyqtgraph-0.14.0-py3-none-any.whl", hash = "sha256:7abb7c3e17362add64f8711b474dffac5e7b0e9245abdf992e9a44119b7aa4f5", size = 1924755, upload-time = "2025-11-16T19:43:22.251Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyreadline3"
|
name = "pyreadline3"
|
||||||
|
|
@ -1694,24 +1460,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
|
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
|
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
|
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1777,28 +1525,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/c1/ab/1d0354b7d1771a28fa7fe089bc23acec2bdd3756efa2419f463e3ed80e16/rapidfuzz-3.14.3-cp313-cp313t-win32.whl", hash = "sha256:489ce98a895c98cad284f0a47960c3e264c724cb4cfd47a1430fa091c0c25204", size = 1757773, upload-time = "2025-11-01T11:53:57.628Z" },
|
{ url = "https://files.pythonhosted.org/packages/c1/ab/1d0354b7d1771a28fa7fe089bc23acec2bdd3756efa2419f463e3ed80e16/rapidfuzz-3.14.3-cp313-cp313t-win32.whl", hash = "sha256:489ce98a895c98cad284f0a47960c3e264c724cb4cfd47a1430fa091c0c25204", size = 1757773, upload-time = "2025-11-01T11:53:57.628Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/0c/71ef356adc29e2bdf74cd284317b34a16b80258fa0e7e242dd92cc1e6d10/rapidfuzz-3.14.3-cp313-cp313t-win_amd64.whl", hash = "sha256:656e52b054d5b5c2524169240e50cfa080b04b1c613c5f90a2465e84888d6f15", size = 1576797, upload-time = "2025-11-01T11:53:59.455Z" },
|
{ url = "https://files.pythonhosted.org/packages/0b/0c/71ef356adc29e2bdf74cd284317b34a16b80258fa0e7e242dd92cc1e6d10/rapidfuzz-3.14.3-cp313-cp313t-win_amd64.whl", hash = "sha256:656e52b054d5b5c2524169240e50cfa080b04b1c613c5f90a2465e84888d6f15", size = 1576797, upload-time = "2025-11-01T11:53:59.455Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/d2/0e64fc27bb08d4304aa3d11154eb5480bcf5d62d60140a7ee984dc07468a/rapidfuzz-3.14.3-cp313-cp313t-win_arm64.whl", hash = "sha256:c7e40c0a0af02ad6e57e89f62bef8604f55a04ecae90b0ceeda591bbf5923317", size = 829940, upload-time = "2025-11-01T11:54:01.1Z" },
|
{ url = "https://files.pythonhosted.org/packages/fe/d2/0e64fc27bb08d4304aa3d11154eb5480bcf5d62d60140a7ee984dc07468a/rapidfuzz-3.14.3-cp313-cp313t-win_arm64.whl", hash = "sha256:c7e40c0a0af02ad6e57e89f62bef8604f55a04ecae90b0ceeda591bbf5923317", size = 829940, upload-time = "2025-11-01T11:54:01.1Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/32/6f/1b88aaeade83abc5418788f9e6b01efefcd1a69d65ded37d89cd1662be41/rapidfuzz-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:442125473b247227d3f2de807a11da6c08ccf536572d1be943f8e262bae7e4ea", size = 1942086, upload-time = "2025-11-01T11:54:02.592Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/2c/b23861347436cb10f46c2bd425489ec462790faaa360a54a7ede5f78de88/rapidfuzz-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1ec0c8c0c3d4f97ced46b2e191e883f8c82dbbf6d5ebc1842366d7eff13cd5a6", size = 1386993, upload-time = "2025-11-01T11:54:04.12Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/83/86/5d72e2c060aa1fbdc1f7362d938f6b237dff91f5b9fc5dd7cc297e112250/rapidfuzz-3.14.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2dc37bc20272f388b8c3a4eba4febc6e77e50a8f450c472def4751e7678f55e4", size = 1379126, upload-time = "2025-11-01T11:54:05.777Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c9/bc/ef2cee3e4d8b3fc22705ff519f0d487eecc756abdc7c25d53686689d6cf2/rapidfuzz-3.14.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dee362e7e79bae940a5e2b3f6d09c6554db6a4e301cc68343886c08be99844f1", size = 3159304, upload-time = "2025-11-01T11:54:07.351Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/36/dc5f2f62bbc7bc90be1f75eeaf49ed9502094bb19290dfb4747317b17f12/rapidfuzz-3.14.3-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:4b39921df948388a863f0e267edf2c36302983459b021ab928d4b801cbe6a421", size = 1218207, upload-time = "2025-11-01T11:54:09.641Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/7e/8f4be75c1bc62f47edf2bbbe2370ee482fae655ebcc4718ac3827ead3904/rapidfuzz-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:beda6aa9bc44d1d81242e7b291b446be352d3451f8217fcb068fc2933927d53b", size = 2401245, upload-time = "2025-11-01T11:54:11.543Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/38/f7c92759e1bb188dd05b80d11c630ba59b8d7856657baf454ff56059c2ab/rapidfuzz-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:6a014ba09657abfcfeed64b7d09407acb29af436d7fc075b23a298a7e4a6b41c", size = 2518308, upload-time = "2025-11-01T11:54:13.134Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c7/ac/85820f70fed5ecb5f1d9a55f1e1e2090ef62985ef41db289b5ac5ec56e28/rapidfuzz-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:32eeafa3abce138bb725550c0e228fc7eaeec7059aa8093d9cbbec2b58c2371a", size = 4265011, upload-time = "2025-11-01T11:54:15.087Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/a9/616930721ea9835c918af7cde22bff17f9db3639b0c1a7f96684be7f5630/rapidfuzz-3.14.3-cp314-cp314-win32.whl", hash = "sha256:adb44d996fc610c7da8c5048775b21db60dd63b1548f078e95858c05c86876a3", size = 1742245, upload-time = "2025-11-01T11:54:17.19Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/06/8a/f2fa5e9635b1ccafda4accf0e38246003f69982d7c81f2faa150014525a4/rapidfuzz-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:f3d15d8527e2b293e38ce6e437631af0708df29eafd7c9fc48210854c94472f9", size = 1584856, upload-time = "2025-11-01T11:54:18.764Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/97/09e20663917678a6d60d8e0e29796db175b1165e2079830430342d5298be/rapidfuzz-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:576e4b9012a67e0bf54fccb69a7b6c94d4e86a9540a62f1a5144977359133583", size = 833490, upload-time = "2025-11-01T11:54:20.753Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/03/1b/6b6084576ba87bf21877c77218a0c97ba98cb285b0c02eaaee3acd7c4513/rapidfuzz-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:cec3c0da88562727dd5a5a364bd9efeb535400ff0bfb1443156dd139a1dd7b50", size = 1968658, upload-time = "2025-11-01T11:54:22.25Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/38/c0/fb02a0db80d95704b0a6469cc394e8c38501abf7e1c0b2afe3261d1510c2/rapidfuzz-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d1fa009f8b1100e4880868137e7bf0501422898f7674f2adcd85d5a67f041296", size = 1410742, upload-time = "2025-11-01T11:54:23.863Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a4/72/3fbf12819fc6afc8ec75a45204013b40979d068971e535a7f3512b05e765/rapidfuzz-3.14.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b86daa7419b5e8b180690efd1fdbac43ff19230803282521c5b5a9c83977655", size = 1382810, upload-time = "2025-11-01T11:54:25.571Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0f/18/0f1991d59bb7eee28922a00f79d83eafa8c7bfb4e8edebf4af2a160e7196/rapidfuzz-3.14.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7bd1816db05d6c5ffb3a4df0a2b7b56fb8c81ef584d08e37058afa217da91b1", size = 3166349, upload-time = "2025-11-01T11:54:27.195Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0d/f0/baa958b1989c8f88c78bbb329e969440cf330b5a01a982669986495bb980/rapidfuzz-3.14.3-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:33da4bbaf44e9755b0ce192597f3bde7372fe2e381ab305f41b707a95ac57aa7", size = 1214994, upload-time = "2025-11-01T11:54:28.821Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/a0/cd12ec71f9b2519a3954febc5740291cceabc64c87bc6433afcb36259f3b/rapidfuzz-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3fecce764cf5a991ee2195a844196da840aba72029b2612f95ac68a8b74946bf", size = 2403919, upload-time = "2025-11-01T11:54:30.393Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/ce/019bd2176c1644098eced4f0595cb4b3ef52e4941ac9a5854f209d0a6e16/rapidfuzz-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ecd7453e02cf072258c3a6b8e930230d789d5d46cc849503729f9ce475d0e785", size = 2508346, upload-time = "2025-11-01T11:54:32.048Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/23/f8/be16c68e2c9e6c4f23e8f4adbb7bccc9483200087ed28ff76c5312da9b14/rapidfuzz-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea188aa00e9bcae8c8411f006a5f2f06c4607a02f24eab0d8dc58566aa911f35", size = 4274105, upload-time = "2025-11-01T11:54:33.701Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/d1/5ab148e03f7e6ec8cd220ccf7af74d3aaa4de26dd96df58936beb7cba820/rapidfuzz-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:7ccbf68100c170e9a0581accbe9291850936711548c6688ce3bfb897b8c589ad", size = 1793465, upload-time = "2025-11-01T11:54:35.331Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/97/433b2d98e97abd9fff1c470a109b311669f44cdec8d0d5aa250aceaed1fb/rapidfuzz-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:9ec02e62ae765a318d6de38df609c57fc6dacc65c0ed1fd489036834fd8a620c", size = 1623491, upload-time = "2025-11-01T11:54:38.085Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/f6/e2176eb94f94892441bce3ddc514c179facb65db245e7ce3356965595b19/rapidfuzz-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:e805e52322ae29aa945baf7168b6c898120fbc16d2b8f940b658a5e9e3999253", size = 851487, upload-time = "2025-11-01T11:54:40.176Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1925,22 +1651,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" },
|
{ url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" },
|
{ url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" },
|
{ url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" },
|
{ url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1970,7 +1680,7 @@ wheels = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tractor"
|
name = "tractor"
|
||||||
version = "0.1.0a6.dev0"
|
version = "0.1.0a6.dev0"
|
||||||
source = { git = "https://github.com/goodboy/tractor.git?branch=piker_pin#36307c59175a1d04fecc77ef2c28f5c943b5f3d1" }
|
source = { git = "https://github.com/goodboy/tractor.git?branch=piker_pin#566a17ba92469000a01fd18c709ea3e336e72796" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "bidict" },
|
{ name = "bidict" },
|
||||||
{ name = "cffi" },
|
{ name = "cffi" },
|
||||||
|
|
@ -2116,18 +1826,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" },
|
{ url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" },
|
{ url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" },
|
{ url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2185,26 +1883,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" },
|
{ url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" },
|
{ url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" },
|
{ url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" },
|
{ url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2300,38 +1978,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" },
|
{ url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" },
|
{ url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" },
|
{ url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" },
|
{ url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue