moved a bunch of garbage (things that have nothing to do in root) to _trash

This commit is contained in:
mia 2025-06-15 22:42:02 +02:00
parent d094982b2c
commit 3226ed29ec
2610 changed files with 0 additions and 0 deletions

View file

@ -1,388 +0,0 @@
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`adafruit_connection_manager`
================================================================================
A urllib3.poolmanager/urllib3.connectionpool-like library for managing sockets and connections
* Author(s): Justin Myers
Implementation Notes
--------------------
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://circuitpython.org/downloads
"""
__version__ = "3.1.4"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ConnectionManager.git"
import errno
import sys
WIZNET5K_SSL_SUPPORT_VERSION = (9, 1)
if not sys.implementation.name == "circuitpython":
from typing import List, Optional, Tuple
from circuitpython_typing.socket import (
CircuitPythonSocketType,
InterfaceType,
SocketpoolModuleType,
SocketType,
SSLContextType,
)
class _FakeSSLSocket:
def __init__(self, socket: CircuitPythonSocketType, tls_mode: int) -> None:
self._socket = socket
self._mode = tls_mode
self.settimeout = socket.settimeout
self.send = socket.send
self.recv = socket.recv
self.close = socket.close
self.recv_into = socket.recv_into
# For sockets that come from software socketpools (like the esp32api), they track
# the interface and socket pool. We need to make sure the clones do as well
self._interface = getattr(socket, "_interface", None)
self._socket_pool = getattr(socket, "_socket_pool", None)
def connect(self, address: Tuple[str, int]) -> None:
"""Connect wrapper to add non-standard mode parameter"""
try:
return self._socket.connect(address, self._mode)
except RuntimeError as error:
raise OSError(errno.ENOMEM, str(error)) from error
class _FakeSSLContext:
def __init__(self, iface: InterfaceType) -> None:
self._iface = iface
def wrap_socket(
self, socket: CircuitPythonSocketType, server_hostname: Optional[str] = None
) -> _FakeSSLSocket:
"""Return the same socket"""
if hasattr(self._iface, "TLS_MODE"):
return _FakeSSLSocket(socket, self._iface.TLS_MODE)
raise ValueError("This radio does not support TLS/HTTPS")
def create_fake_ssl_context(
socket_pool: SocketpoolModuleType, iface: InterfaceType
) -> _FakeSSLContext:
"""Method to return a fake SSL context for when ssl isn't available to import
For example when using a:
* `Adafruit Ethernet FeatherWing <https://www.adafruit.com/product/3201>`_
* `Adafruit AirLift ESP32 WiFi Co-Processor Breakout Board
<https://www.adafruit.com/product/4201>`_
* `Adafruit AirLift FeatherWing ESP32 WiFi Co-Processor
<https://www.adafruit.com/product/4264>`_
"""
if hasattr(socket_pool, "set_interface"):
# this is to manually support legacy hardware like the fona
socket_pool.set_interface(iface)
return _FakeSSLContext(iface)
class CPythonNetwork:
"""Radio object to use when using ConnectionManager in CPython."""
_global_connection_managers = {}
_global_key_by_socketpool = {}
_global_socketpools = {}
_global_ssl_contexts = {}
def _get_radio_hash_key(radio):
try:
return hash(radio)
except TypeError:
return radio.__class__.__name__
def get_radio_socketpool(radio):
"""Helper to get a socket pool for common boards.
Currently supported:
* Boards with onboard WiFi (ESP32S2, ESP32S3, Pico W, etc)
* Using the ESP32 WiFi Co-Processor (like the Adafruit AirLift)
* Using a WIZ5500 (Like the Adafruit Ethernet FeatherWing)
"""
key = _get_radio_hash_key(radio)
if key not in _global_socketpools:
class_name = radio.__class__.__name__
if class_name == "Radio":
import ssl
import socketpool
pool = socketpool.SocketPool(radio)
ssl_context = ssl.create_default_context()
elif class_name == "ESP_SPIcontrol":
import adafruit_esp32spi.adafruit_esp32spi_socketpool as socketpool
pool = socketpool.SocketPool(radio)
ssl_context = create_fake_ssl_context(pool, radio)
elif class_name == "WIZNET5K":
import adafruit_wiznet5k.adafruit_wiznet5k_socketpool as socketpool
pool = socketpool.SocketPool(radio)
# Note: At this time, SSL/TLS connections are not supported by older
# versions of the Wiznet5k library or on boards withouut the ssl module
# see https://docs.circuitpython.org/en/latest/shared-bindings/support_matrix.html
ssl_context = None
implementation_name = sys.implementation.name
implementation_version = sys.implementation.version
if (
pool.SOCK_STREAM == 1
and implementation_name == "circuitpython"
and implementation_version >= WIZNET5K_SSL_SUPPORT_VERSION
):
try:
import ssl
ssl_context = ssl.create_default_context()
except ImportError:
# if SSL not on board, default to fake_ssl_context
pass
if ssl_context is None:
ssl_context = create_fake_ssl_context(pool, radio)
elif class_name == "CPythonNetwork":
import socket as pool
import ssl
ssl_context = ssl.create_default_context()
else:
raise ValueError(f"Unsupported radio class: {class_name}")
_global_key_by_socketpool[pool] = key
_global_socketpools[key] = pool
_global_ssl_contexts[key] = ssl_context
return _global_socketpools[key]
def get_radio_ssl_context(radio):
"""Helper to get ssl_contexts for common boards.
Currently supported:
* Boards with onboard WiFi (ESP32S2, ESP32S3, Pico W, etc)
* Using the ESP32 WiFi Co-Processor (like the Adafruit AirLift)
* Using a WIZ5500 (Like the Adafruit Ethernet FeatherWing)
"""
get_radio_socketpool(radio)
return _global_ssl_contexts[_get_radio_hash_key(radio)]
class ConnectionManager:
"""A library for managing sockets across multiple hardware platforms and libraries."""
def __init__(
self,
socket_pool: SocketpoolModuleType,
) -> None:
self._socket_pool = socket_pool
# Hang onto open sockets so that we can reuse them.
self._available_sockets = set()
self._key_by_managed_socket = {}
self._managed_socket_by_key = {}
def _free_sockets(self, force: bool = False) -> None:
# cloning lists since items are being removed
available_sockets = list(self._available_sockets)
for socket in available_sockets:
self.close_socket(socket)
if force:
open_sockets = list(self._managed_socket_by_key.values())
for socket in open_sockets:
self.close_socket(socket)
def _register_connected_socket(self, key, socket):
"""Register a socket as managed."""
self._key_by_managed_socket[socket] = key
self._managed_socket_by_key[key] = socket
def _get_connected_socket(
self,
addr_info: List[Tuple[int, int, int, str, Tuple[str, int]]],
host: str,
port: int,
timeout: float,
is_ssl: bool,
ssl_context: Optional[SSLContextType] = None,
):
socket = self._socket_pool.socket(addr_info[0], addr_info[1])
if is_ssl:
socket = ssl_context.wrap_socket(socket, server_hostname=host)
connect_host = host
else:
connect_host = addr_info[-1][0]
# Set socket read and connect timeout.
socket.settimeout(timeout)
try:
socket.connect((connect_host, port))
except (MemoryError, OSError):
# If any connect problems, clean up and re-raise the problem exception.
socket.close()
raise
return socket
@property
def available_socket_count(self) -> int:
"""Get the count of available (freed) managed sockets."""
return len(self._available_sockets)
@property
def managed_socket_count(self) -> int:
"""Get the count of managed sockets."""
return len(self._managed_socket_by_key)
def close_socket(self, socket: SocketType) -> None:
"""
Close a previously managed and connected socket.
- **socket_pool** *(SocketType)* The socket you want to close
"""
if socket not in self._managed_socket_by_key.values():
raise RuntimeError("Socket not managed")
socket.close()
key = self._key_by_managed_socket.pop(socket)
del self._managed_socket_by_key[key]
if socket in self._available_sockets:
self._available_sockets.remove(socket)
def free_socket(self, socket: SocketType) -> None:
"""Mark a managed socket as available so it can be reused. The socket is not closed."""
if socket not in self._managed_socket_by_key.values():
raise RuntimeError("Socket not managed")
self._available_sockets.add(socket)
def get_socket(
self,
host: str,
port: int,
proto: str,
session_id: Optional[str] = None,
*,
timeout: float = 1.0,
is_ssl: bool = False,
ssl_context: Optional[SSLContextType] = None,
) -> CircuitPythonSocketType:
"""
Get a new socket and connect to the given host.
:param str host: host to connect to, such as ``"www.example.org"``
:param int port: port to use for connection, such as ``80`` or ``443``
:param str proto: connection protocol: ``"http:"``, ``"https:"``, etc.
:param Optional[str]: unique session ID,
used for multiple simultaneous connections to the same host
:param float timeout: how long to wait to connect
:param bool is_ssl: ``True`` If the connection is to be over SSL;
automatically set when ``proto`` is ``"https:"``
:param Optional[SSLContextType]: SSL context to use when making SSL requests
"""
if session_id:
session_id = str(session_id)
key = (host, port, proto, session_id)
# Do we have already have a socket available for the requested connection?
if key in self._managed_socket_by_key:
socket = self._managed_socket_by_key[key]
if socket in self._available_sockets:
self._available_sockets.remove(socket)
return socket
raise RuntimeError(f"An existing socket is already connected to {proto}//{host}:{port}")
if proto == "https:":
is_ssl = True
if is_ssl and not ssl_context:
raise ValueError("ssl_context must be provided if using ssl")
addr_info = self._socket_pool.getaddrinfo(host, port, 0, self._socket_pool.SOCK_STREAM)[0]
try:
socket = self._get_connected_socket(addr_info, host, port, timeout, is_ssl, ssl_context)
self._register_connected_socket(key, socket)
return socket
except (MemoryError, OSError, RuntimeError):
# Could not get a new socket (or two, if SSL).
# If there are any available sockets, free them all and try again.
if self.available_socket_count:
self._free_sockets()
socket = self._get_connected_socket(
addr_info, host, port, timeout, is_ssl, ssl_context
)
self._register_connected_socket(key, socket)
return socket
# Re-raise exception if no sockets could be freed.
raise
def connection_manager_close_all(
socket_pool: Optional[SocketpoolModuleType] = None, release_references: bool = False
) -> None:
"""
Close all open sockets for pool, optionally release references.
:param Optional[SocketpoolModuleType] socket_pool:
a specific socket pool whose sockets you want to close; ``None`` means all socket pools
:param bool release_references: ``True`` if you also want the `ConnectionManager` to forget
all the socket pools and SSL contexts it knows about
"""
if socket_pool:
socket_pools = [socket_pool]
else:
socket_pools = _global_connection_managers.keys()
for pool in socket_pools:
connection_manager = _global_connection_managers.get(pool, None)
if connection_manager is None:
raise RuntimeError("SocketPool not managed")
connection_manager._free_sockets(force=True)
if not release_references:
continue
key = _global_key_by_socketpool.pop(pool)
if key:
_global_socketpools.pop(key, None)
_global_ssl_contexts.pop(key, None)
_global_connection_managers.pop(pool, None)
def get_connection_manager(socket_pool: SocketpoolModuleType) -> ConnectionManager:
"""
Get or create the ConnectionManager singleton for the given pool.
"""
if socket_pool not in _global_connection_managers:
_global_connection_managers[socket_pool] = ConnectionManager(socket_pool)
return _global_connection_managers[socket_pool]