Skip to content

Commit

Permalink
Merge pull request #460 from kytos-ng/upgrade/python
Browse files Browse the repository at this point in the history
chore: Upgraded python and dependencies
  • Loading branch information
viniarck authored Mar 28, 2024
2 parents 6652ed5 + a6b65ba commit 2f17b40
Show file tree
Hide file tree
Showing 28 changed files with 477 additions and 403 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.9'
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.9]
python-version: [3.11]

steps:
- uses: actions/checkout@v1
Expand Down
2 changes: 1 addition & 1 deletion .scrutinizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ checks:
duplicate_code: true
build:
environment:
python: 3.9.12
python: 3.11.8
postgresql: false
redis: false
dependencies:
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ python:
- "3.7"
- "3.8"
- "3.9"
- "3.11"
install:
- pip install --upgrade pip
- pip install -r requirements/dev.txt
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ All notable changes to the kytos project will be documented in this file.
UNRELEASED - Under development
******************************

Changed
=======
- Updated python environment installation from 3.9 to 3.11
- Updated test dependencies

[2023.2.0] - 2024-02-16
***********************

Expand Down
9 changes: 6 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ Installing
==========

If you don't have Python 3 installed, please install it. Please make
sure that you're using ``python3.9``:
sure that you're using ``python3.11`` and dependencies:

.. code-block:: shell
$ apt install python3.9
$ apt install python3.11 python3.11-dev python3.11-venv
Then, the first step is to clone *kytos* repository:

Expand All @@ -64,7 +64,10 @@ install procedure:
.. code-block:: shell
$ cd kytos
$ sudo python3 setup.py install
$ sudo python3 -m pip install .
For a complete installation procedure visit our
`development environment setup <https://github.com/kytos-ng/documentation/blob/master/tutorials/napps/development_environment_setup.rst>`_.

Configuring
===========
Expand Down
3 changes: 1 addition & 2 deletions kytos/core/api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,7 @@ def _get_decorated_functions(napp):
and isinstance(pub_attr.route_index, int)
):
callables.append(pub_attr)
for pub_attr in sorted(callables, key=lambda f: f.route_index):
yield pub_attr
yield from sorted(callables, key=lambda f: f.route_index)

@classmethod
def get_absolute_rule(cls, rule, napp):
Expand Down
5 changes: 2 additions & 3 deletions kytos/core/atcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def __init__(self):
if not self.server:
raise ValueError("server instance must be assigned before init")

def connection_made(self, transport):
def connection_made(self, transport: asyncio.Transport):
"""Handle new client connection, passing it to the controller.
Build a new Kytos `Connection` and send a ``kytos/core.connection.new``
Expand All @@ -126,11 +126,10 @@ def connection_made(self, transport):

addr, port = transport.get_extra_info('peername')
_, server_port = transport.get_extra_info('sockname')
socket = transport.get_extra_info('socket')

LOG.info("New connection from %s:%s", addr, port)

self.connection = Connection(addr, port, socket)
self.connection = Connection(addr, port, transport)

# This allows someone to inherit from KytosServer and start a server
# on another port to handle a different protocol.
Expand Down
8 changes: 4 additions & 4 deletions kytos/core/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
content_type_json_or_415, error_msg,
get_json_or_400)
from kytos.core.retry import before_sleep, for_all_methods, retries
from kytos.core.user import HashSubDoc, UserDoc, UserDocUpdate
from kytos.core.user import HashSubDoc, UserDoc, UserDocUpdate, hashing

__all__ = ['authenticated']

Expand Down Expand Up @@ -110,7 +110,7 @@ def create_user(self, user_data: dict) -> InsertOneResult:
"email": user_data.get('email'),
"inserted_at": utc_now,
"updated_at": utc_now,
}).dict())
}).model_dump())
except DuplicateKeyError as err:
raise err
except ValidationError as err:
Expand Down Expand Up @@ -142,7 +142,7 @@ def update_user(self, username: str, data: dict) -> dict:
"$set": UserDocUpdate(**{
**data,
**{"updated_at": utc_now}
}).dict(exclude_none=True)
}).model_dump(exclude_none=True)
},
return_document=ReturnDocument.AFTER
)
Expand Down Expand Up @@ -307,7 +307,7 @@ def _authenticate_user(self, request: Request) -> JSONResponse:
user = self._find_user(username)
if user["state"] != 'active':
raise HTTPException(401, detail='This user is not active')
password_hashed = UserDoc.hashing(password, user["hash"])
password_hashed = hashing(password, user["hash"])
if user["password"] != password_hashed:
raise HTTPException(401, detail="Incorrect password")
time_exp = datetime.datetime.utcnow() + datetime.timedelta(
Expand Down
29 changes: 17 additions & 12 deletions kytos/core/connection.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
"""Module with main classes related to Connections."""
import logging
from asyncio import Transport
from enum import Enum
from errno import EBADF, ENOTCONN
from socket import SHUT_RDWR
from socket import error as SocketError

__all__ = ('Connection', 'ConnectionProtocol', 'ConnectionState')

Expand Down Expand Up @@ -33,19 +32,25 @@ def __init__(self, name=None, version=None, state=None):
class Connection:
"""Connection class to abstract a network connections."""

def __init__(self, address, port, socket, switch=None):
def __init__(
self,
address: str,
port: int,
transport: Transport,
switch=None
):
"""Assign parameters to instance variables.
Args:
address (|hw_address|): Source address.
port (int): Port number.
socket (socket): socket.
transport (Transport): transport.
switch (:class:`~.Switch`): switch with this connection.
"""
self.address = address
self.port = port
self.socket = socket
self.switch = switch
self.transport = transport
self.state = ConnectionState.NEW
self.protocol = ConnectionProtocol()
self.remaining_data = b''
Expand All @@ -55,7 +60,7 @@ def __str__(self):

def __repr__(self):
return f"Connection({self.address!r}, {self.port!r}," + \
f" {self.socket!r}, {self.switch!r}, {self.state!r})"
f" {self.transport!r}, {self.switch!r}, {self.state!r})"

@property
def state(self):
Expand All @@ -65,6 +70,7 @@ def state(self):
@state.setter
def state(self, new_state):
if new_state not in ConnectionState:
# pylint: disable=broad-exception-raised
raise Exception('Unknown State', new_state)
# pylint: disable=attribute-defined-outside-init
self._state = new_state
Expand All @@ -90,8 +96,8 @@ def send(self, buffer):
"""
try:
if self.is_alive():
self.socket.sendall(buffer)
except (OSError, SocketError) as exception:
self.transport.write(buffer)
except OSError as exception:
LOG.debug('Could not send packet. Exception: %s', exception)
self.close()
raise
Expand All @@ -102,9 +108,8 @@ def close(self):
LOG.debug('Shutting down Connection %s', self.id)

try:
self.socket.shutdown(SHUT_RDWR)
self.socket.close()
self.socket = None
self.transport.close()
self.transport = None
LOG.debug('Connection Closed: %s', self.id)
except OSError as exception:
if exception.errno not in (ENOTCONN, EBADF):
Expand All @@ -114,7 +119,7 @@ def close(self):

def is_alive(self):
"""Return True if the connection socket is alive. False otherwise."""
return self.socket is not None and self.state not in (
return self.transport is not None and self.state not in (
ConnectionState.FINISHED, ConnectionState.FAILED)

def is_new(self):
Expand Down
15 changes: 10 additions & 5 deletions kytos/core/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from importlib import reload as reload_module
from importlib.util import module_from_spec, spec_from_file_location
from pathlib import Path
from socket import error as SocketError

from pyof.foundation.exceptions import PackException

Expand All @@ -38,7 +37,7 @@
from kytos.core.auth import Auth
from kytos.core.buffers import KytosBuffers
from kytos.core.config import KytosConfig
from kytos.core.connection import ConnectionState
from kytos.core.connection import Connection, ConnectionState
from kytos.core.db import db_conn_wait
from kytos.core.dead_letter import DeadLetter
from kytos.core.events import KytosEvent
Expand Down Expand Up @@ -107,7 +106,7 @@ def __init__(self, options=None, loop: AbstractEventLoop = None):
#: This dict stores all connections between the controller and the
#: switches. The key for this dict is a tuple (ip, port). The content
#: is a Connection
self.connections = {}
self.connections: dict[tuple, Connection] = {}
#: dict: mapping of events and event listeners.
#:
#: The key of the dict is a KytosEvent (or a string that represent a
Expand Down Expand Up @@ -155,6 +154,9 @@ def __init__(self, options=None, loop: AbstractEventLoop = None):
self._alisten_tasks = set()
self.qmonitors: list[QueueMonitorWindow] = []

#: APM client in memory to be closed when necessary
self.apm = None

self._register_endpoints()
#: Adding the napps 'enabled' directory into the PATH
#: Now you can access the enabled napps with:
Expand Down Expand Up @@ -259,7 +261,7 @@ def start(self, restart=False):
db_conn_wait(db_backend=self.options.database)
self.start_auth()
if self.options.apm:
init_apm(self.options.apm, app=self.api_server.app)
self.apm = init_apm(self.options.apm, app=self.api_server.app)
if not restart:
self.create_pidfile()
self.start_controller()
Expand Down Expand Up @@ -509,6 +511,9 @@ def stop_controller(self, graceful=True):
# self.server.server_close()

self.stop_queue_monitors()
if self.apm:
self.log.info("Stopping APM server...")
self.apm.close()
self.log.info("Stopping API Server...")
self.api_server.stop()
self.log.info("Stopped API Server")
Expand Down Expand Up @@ -626,7 +631,7 @@ async def msg_out_event_handler(self):
message.header.xid,
packet.hex())
self.notify_listeners(triggered_event)
except (OSError, SocketError):
except OSError:
await self.publish_connection_error(triggered_event)
self.log.info("connection closed. Cannot send message")
except PackException as err:
Expand Down
4 changes: 2 additions & 2 deletions kytos/core/dead_letter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import List

# pylint: disable=no-name-in-module,invalid-name
from pydantic import BaseModel, ValidationError, constr
from pydantic import BaseModel, Field, ValidationError

# pylint: enable=no-name-in-module
from kytos.core.rest_api import (HTTPException, JSONResponse, Request,
Expand All @@ -22,7 +22,7 @@ class KytosQueueBufferNames(str, Enum):
class DeadLetterDeletePayload(BaseModel):
"""DeadLetterDeletePayload."""

event_name: constr(min_length=1)
event_name: str = Field(min_length=1)
ids: List[str] = []


Expand Down
Loading

0 comments on commit 2f17b40

Please sign in to comment.