8000 Simplified connection manager API by mjcaley · Pull Request #225 · mjcaley/aiospamc · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Simplified connection manager API #225

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

Merged
merged 8 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 4 additions & 8 deletions aiospamc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

'''Contains the Client class that is used to interact with SPAMD.'''

import asyncio
import logging
from pathlib import Path
import ssl
Expand Down Expand Up @@ -42,10 +41,10 @@ def __init__(self,
'''

if socket_path:
from aiospamc.connections.unix_connection import UnixConnectionManager
from aiospamc.connections import UnixConnectionManager
self.connection = UnixConnectionManager(socket_path)
elif host and port:
from aiospamc.connections.tcp_connection import TcpConnectionManager
from aiospamc.connections import TcpConnectionManager
if verify is not None:
self.connection = TcpConnectionManager(host, port, self.new_ssl_context(verify))
else:
Expand All @@ -63,7 +62,7 @@ def __init__(self,
self.logger.debug('Created instance of %r', self)

def __repr__(self) -> str:
return f'{self.__class__.__name__}(socket_path={self._socker_path}, ' \
return f'{self.__class__.__name__}(socket_path={self._socket_path}, ' \
f'host={repr(self._host)}, port={repr(self._port)}, ' \
f'user={repr(self.user)}, compress={repr(self.compress)})'

Expand Down Expand Up @@ -125,10 +124,7 @@ async def send(self, request: Request) -> Response:
request.headers['User'] = self.user

self.logger.debug('Sending request (%s)', id(request))
async with self.connection.new_connection() as connection:
await connection.send(bytes(request))
self.logger.debug('Request (%s) successfully sent', id(request))
data = await connection.receive()
data = await self.connection.request(bytes(request))

try:
try:
Expand Down
127 changes: 127 additions & 0 deletions aiospamc/connections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python

'''Connection and ConnectionManager base classes.'''

from aiospamc.exceptions import AIOSpamcConnectionFailed
import asyncio
import logging
from ssl import SSLContext
from typing import Tuple


class ConnectionManager:
'''Stores connection parameters and creates connections.'''

def __init__(self) -> None:
self._logger = logging.getLogger(__name__)

@property
def logger(self) -> logging.Logger:
'''Return the logger object.'''

return self._logger

async def request(self, data: bytes) -> bytes:
'''Send bytes data and receive a response.

:param data: Data to send.
'''

reader, writer = await self.open()

writer.write(data)
await writer.drain()

response = await reader.read()

writer.close()

return response

async def open(self) -> Tuple[asyncio.StreamReader, asyncio.StreamWriter]:
'''Opens a connection, returning the reader and writer objects.'''

raise NotImplementedError

@property
def connection_string(self) -> str:
'''String representation of the connection.'''

raise NotImplementedError


class TcpConnectionManager(ConnectionManager):
def __init__(self, host: str, port: int, ssl: SSLContext = None) -> None:
'''TcpConnectionManager constructor.

:param host: Hostname or IP address.
:param port: TCP port.
:param ssl: SSL context.
'''

super().__init__()
self.host = host
self.port = port
self.ssl = ssl

async def open(self) -> Tuple[asyncio.StreamReader, asyncio.StreamWriter]:
'''Opens a TCP connection.

:raises: AIOSpamcConnectionFailed

:return: Reader and writer for the connection.
'''

try:
reader, writer = await asyncio.open_connection(self.host,
self.port,
ssl=self.ssl)
except (ConnectionRefusedError, OSError) as error:
raised = AIOSpamcConnectionFailed(error)
self.logger.exception('Exception occurred when connecting to %s:%s: %s',
self.host,
self.port,
raised)
raise raised

return reader, writer

@property
def connection_string(self) -> str:
''':return: TCP hostname/IP and port.'''

return ':'.join([self.host, str(self.port)])


class UnixConnectionManager(ConnectionManager):
def __init__(self, path: str):
'''UnixConnectionManager constructor.

:param path: Unix socket path.
'''

super().__init__()
self.path = path

async def open(self) -> Tuple[asyncio.StreamReader, asyncio.StreamWriter]:
'''Opens a unix socket path connection.

:raises: AIOSpamcConnectionFailed

:return: Reader and writer for the connection.
'''

try:
reader, writer = await asyncio.open_unix_connection(self.path)
except (ConnectionRefusedError, OSError) as error:
raised = AIOSpamcConnectionFailed(error)
self.logger.exception('Exception occurred when connecting: %s', raised)
raise raised

return reader, writer

@property
def connection_string(self) -> str:
''':return: Unix connection path.'''

return self.path
70 changes: 0 additions & 70 deletions aiospamc/connections/__init__.py

This file was deleted.

87 changes: 0 additions & 87 deletions aiospamc/connections/tcp_connection.py

This file was deleted.

Loading
0