Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full Typing of Spinnman classes #425

Merged
merged 25 commits into from
Nov 19, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
typing
Christian-B committed Oct 28, 2024
commit 3fda297a5dfdfc817460009e271c4b936c181da0
48 changes: 27 additions & 21 deletions spinnman/spalloc/session.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
from logging import getLogger
from json.decoder import JSONDecodeError
import re
from typing import Dict, Tuple, cast, Optional
from typing import Any, Callable, Dict, Tuple, cast, Optional
import websocket # type: ignore

import requests
@@ -34,8 +34,8 @@
_debug_pretty_print = False


def _may_renew(method):
def pp_req(request: requests.PreparedRequest):
def _may_renew(method: Callable) -> Callable:
def pp_req(request: requests.PreparedRequest) -> None:
"""
:param ~requests.PreparedRequest request:
"""
@@ -47,7 +47,7 @@ def pp_req(request: requests.PreparedRequest):
if request.body:
print(request.body)

def pp_resp(response: requests.Response):
def pp_resp(response: requests.Response) -> None:
"""
:param ~requests.Response response:
"""
@@ -61,7 +61,7 @@ def pp_resp(response: requests.Response):
str(response.content, "UTF-8") if response.content else ""))

@wraps(method)
def call(self, *args, **kwargs):
def call(self: 'Session', *args: Any, **kwargs: Any) -> None:
renew_count = 0
while True:
r = method(self, *args, **kwargs)
@@ -115,16 +115,17 @@ def __init__(
if session_credentials:
cookies, headers = session_credentials
if _SESSION_COOKIE in cookies:
self._session_id = cookies[_SESSION_COOKIE]
self._session_id: Optional[str] = cookies[_SESSION_COOKIE]
for key, value in headers.items():
if key == "Authorization":
# TODO: extract this?
pass
else:
self.__csrf_header = key
self.__csrf = value
self.__csrf: Optional[str] = value

def __handle_error_or_return(self, response: requests.Response):
def __handle_error_or_return(self, response: requests.Response
) -> Optional[requests.Response]:
code = response.status_code
if code >= 200 and code < 400:
return response
@@ -133,7 +134,8 @@ def __handle_error_or_return(self, response: requests.Response):
f" {str(result)}")

@_may_renew
def get(self, url: str, timeout: int = 10, **kwargs) -> requests.Response:
def get(self, url: str, timeout: int = 10, **kwargs: Any
) -> Optional[requests.Response]:
"""
Do an HTTP ``GET`` in the session.

@@ -143,6 +145,7 @@ def get(self, url: str, timeout: int = 10, **kwargs) -> requests.Response:
:raise ValueError: If the server rejects a request
"""
params = kwargs if kwargs else None
assert self._session_id is not None
cookies = {_SESSION_COOKIE: self._session_id}
r = requests.get(url, params=params, cookies=cookies,
allow_redirects=False, timeout=timeout)
@@ -151,7 +154,7 @@ def get(self, url: str, timeout: int = 10, **kwargs) -> requests.Response:

@_may_renew
def post(self, url: str, json_dict: dict, timeout: int = 10,
**kwargs) -> requests.Response:
**kwargs: Any) -> Optional[requests.Response]:
"""
Do an HTTP ``POST`` in the session.

@@ -171,7 +174,7 @@ def post(self, url: str, json_dict: dict, timeout: int = 10,

@_may_renew
def put(self, url: str, data: str, timeout: int = 10,
**kwargs) -> requests.Response:
**kwargs: Any) -> Optional[requests.Response]:
"""
Do an HTTP ``PUT`` in the session. Puts plain text *OR* JSON!

@@ -193,7 +196,7 @@ def put(self, url: str, data: str, timeout: int = 10,

@_may_renew
def delete(self, url: str, timeout: int = 10,
**kwargs) -> requests.Response:
**kwargs: Any) -> Optional[requests.Response]:
"""
Do an HTTP ``DELETE`` in the session.

@@ -288,6 +291,8 @@ def _credentials(self) -> Tuple[Dict[str, str], Dict[str, str]]:
"""
The credentials for requests. *Serializable.*
"""
assert self._session_id is not None
assert self.__csrf is not None
cookies = {_SESSION_COOKIE: self._session_id}
headers = {self.__csrf_header: self.__csrf}
if self.__token:
@@ -297,7 +302,7 @@ def _credentials(self) -> Tuple[Dict[str, str], Dict[str, str]]:

def websocket(
self, url: str, header: Optional[dict] = None,
cookie: Optional[str] = None, **kwargs) -> websocket.WebSocket:
cookie: Optional[str] = None, **kwargs: Any) -> websocket.WebSocket:
"""
Create a websocket that uses the session credentials to establish
itself.
@@ -313,14 +318,15 @@ def websocket(
if header is None:
header = {}
header[self.__csrf_header] = self.__csrf
assert self._session_id is not None
if cookie is not None:
cookie += ";" + _SESSION_COOKIE + "=" + self._session_id
else:
cookie = _SESSION_COOKIE + "=" + self._session_id
return websocket.create_connection(
url, header=header, cookie=cookie, **kwargs)

def _purge(self):
def _purge(self) -> None:
"""
Clears out all credentials from this session, rendering the session
completely inoperable henceforth.
@@ -345,7 +351,7 @@ def __init__(self, session: Session, url: str):
self._url = clean_url(url)

@property
def _session_credentials(self):
def _session_credentials(self) -> Tuple[Dict[str, str], Dict[str, str]]:
"""
The current session credentials.
Only supposed to be called by subclasses.
@@ -356,7 +362,7 @@ def _session_credentials(self):
return self.__session._credentials

@property
def _service_url(self):
def _service_url(self) -> str:
"""
The main service URL.

@@ -365,19 +371,19 @@ def _service_url(self):
# pylint: disable=protected-access
return self.__session._service_url

def _get(self, url: str, **kwargs) -> requests.Response:
def _get(self, url: str, **kwargs: Any) -> requests.Response:
return self.__session.get(url, **kwargs)

def _post(self, url: str, json_dict: dict, **kwargs) -> requests.Response:
def _post(self, url: str, json_dict: dict, **kwargs: Any) -> requests.Response:
return self.__session.post(url, json_dict, **kwargs)

def _put(self, url: str, data: str, **kwargs) -> requests.Response:
def _put(self, url: str, data: str, **kwargs: Any) -> requests.Response:
return self.__session.put(url, data, **kwargs)

def _delete(self, url: str, **kwargs) -> requests.Response:
def _delete(self, url: str, **kwargs: Any) -> requests.Response:
return self.__session.delete(url, **kwargs)

def _websocket(self, url: str, **kwargs) -> websocket.WebSocket:
def _websocket(self, url: str, **kwargs: Any) -> websocket.WebSocket:
"""
Create a websocket that uses the session credentials to establish
itself.
2 changes: 1 addition & 1 deletion spinnman/spalloc/spalloc_proxied_connection.py
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ class SpallocProxiedConnection(Listenable, metaclass=AbstractBase):
__slots__ = ()

@abstractmethod
def send(self, data: bytes):
def send(self, data: bytes) -> None:
"""
Send a message on an open socket.

9 changes: 6 additions & 3 deletions spinnman/utilities/locate_connected_machine_ip_address.py
Original file line number Diff line number Diff line change
@@ -16,11 +16,14 @@
import sys
import signal
import socket
from typing import Callable
from types import FrameType
from typing import Callable, Optional

from typing_extensions import Never
from spinnman.connections.udp_packet_connections import IPAddressesConnection


def locate_connected_machine(handler: Callable[[str, float], bool]):
def locate_connected_machine(handler: Callable[[str, float], bool]) -> None:
"""
Locates any SpiNNaker machines IP addresses from the auto-transmitted
packets from non-booted SpiNNaker machines.
@@ -43,7 +46,7 @@ def locate_connected_machine(handler: Callable[[str, float], bool]):


if __name__ == "__main__":
def _ctrlc_handler(sig, frame):
def _ctrlc_handler(sig: int, frame: Optional[FrameType]) -> Never:
"""
:return: Never returns as it causes a sys.exit()
"""