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

Version 6.0.0 merge request #292

Merged
merged 28 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
48e1bdc
fix: Fix some docstring
franjuan Sep 10, 2024
2241d6c
fix: auxiliary Echo server for testing improved and adapted to new as…
franjuan Sep 10, 2024
e9aea9e
fix: lastest version of Python requires date operations to include ti…
franjuan Sep 10, 2024
f4ea18a
fix: SSL wrapping for no certificates context
franjuan Sep 10, 2024
c38e179
chore: Extend supported Python versions to 10, 11 and 12
franjuan Sep 10, 2024
60c289e
chore: Prepare version
franjuan Sep 10, 2024
4728128
chore: Python versions reordered to perform tests from bigger to smaller
franjuan Sep 10, 2024
2c7d70f
fix: setuptools install forced in ci script
franjuan Sep 11, 2024
614eb27
fix: Updated UTC reference in dependencies to allow support in Python…
franjuan Sep 11, 2024
ab14555
fix: Removed stopit dependency in unit tests due to deprecated depend…
franjuan Sep 11, 2024
095d457
fix: Typo in pebble dependency
franjuan Sep 11, 2024
1dec67f
feat: Python 3.8 support rejected
franjuan Sep 11, 2024
5174b86
fix: TimeoutError reference fixed
franjuan Sep 11, 2024
90860ce
chore: Version 6.0.0 doc amendments
franjuan Sep 11, 2024
9ef124c
fix: PyYaml dependency opened for bigger compatibility
franjuan Oct 1, 2024
64e9cf2
chore: deprecation warning added
franjuan Oct 1, 2024
28c2579
test: improve pytest verbosity
franjuan Oct 2, 2024
8aecca0
Fix[AWS Jobs]: Fixed destination jobs in AWS/Serrea
Worvast Oct 2, 2024
24b30ac
fix: Added error message missing ERROR_AFTER_TIMEOUT
franjuan Oct 3, 2024
24d0be7
fix: Jobs API review and fix
franjuan Oct 4, 2024
3aed0e8
test: Added timeout to unit test of queries to API
franjuan Oct 4, 2024
9cb2cf9
chore: Merge from master
franjuan Oct 4, 2024
bee754f
chore: CHANGELOG.md review
franjuan Oct 4, 2024
a75cfc1
fix: PEP8 formatting
franjuan Oct 4, 2024
ab39f0a
fix: PEP8 formatting
franjuan Oct 4, 2024
84777b4
fix: `destination` no keep alive
franjuan Oct 4, 2024
6adac2d
fix: status when task is removed
franjuan Oct 4, 2024
00cadec
chore: CHANGELOG.md review
franjuan Oct 4, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/python-prereleased.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.9"
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
max-parallel: 1
matrix:
version: ["3.8", "3.9"]
version: [ "3.12", "3.11", "3.10", "3.9" ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -61,4 +61,4 @@ jobs:
export DEVO_SENDER_CHAIN=$(realpath certs/us/ca.crt)
export TMPDIR=${PWD}
cd tests
python -m pytest
python -m pytest -vvv
2 changes: 1 addition & 1 deletion .github/workflows/python-released.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.9"
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [6.0.0] - 2024-10-07

### Changed
- Supported Python versions extended to 10, 11 and 12
- Added time zones in date operations
- Jobs API reviewed and fixed. Jobs searching by type and friendlyName discontinued as it is not supported by API.
Jobs API unit test checked and enabled
- Added timeout to unit tests of API queries. They may run forever when faulty

### Fixed
- Keep-alive mechanism not working for queries with `destination`. Forcing NO_KEEP_ALIVE in queries with
`destination`.
- SSL wrapping of the TCP connection when no certificates are used improved
- Fix auxiliary Echo serving for unit testing in order to run with new async paradigm
- Documentation fixes. Some parameters missing or non-existent in docstring
- Fix for a unit test when using concurrency (from library `stopit` to `pebble`)

### Removed
- Python 3.8 support discontinued

### Incompatibilities with 5.x.x that caused mayor version bump
- Python 3.8 not supported anymore
- Jobs searching by type and friendlyName discontinued in Jobs API. Only search by job id is supported.
- Date requires time zone
- Query with `destination` are forced to NO_KEEP_ALIVE mode for Keep-alive mechanism (instead of
DEFAULT_KEEPALIVE_TOKEN)

## [5.4.1] - 2024-09-13

### Security
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ This is the SDK to access Devo directly from Python. It can be used to:

## Requirements

The Devo SDK for Python requires Python 3.8+
The Devo SDK for Python requires Python 3.9+

## Compatibility

- Tested compatibility for python 3.8 and 3.9
- Tested compatibility for python 3.9, 3.10, 3.11 and 3.12

## Quick Start

Expand Down
2 changes: 1 addition & 1 deletion devo/__version__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__description__ = "Devo Python Library."
__url__ = "http://www.devo.com"
__version__ = "5.4.1"
__version__ = "6.0.0"
__author__ = "Devo"
__author_email__ = "[email protected]"
__license__ = "MIT"
Expand Down
24 changes: 12 additions & 12 deletions devo/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
"connection_error": "Failed to establish a new connection",
"other_errors": "Error while invoking query",
"error_no_detail": "Error code %d while invoking query",
"no_keepalive_for_destination": "Queries with destination functionality only support No Keepalive mode. Forced to"
" NO_KEEP_ALIVE"
}

DEFAULT_KEEPALIVE_TOKEN = "\n"
Expand Down Expand Up @@ -173,6 +175,7 @@ def __init__(
self.processor = None
self.set_processor(processor)
self.keepAliveToken = None

self.set_keepalive_token(keepAliveToken)

if pragmas:
Expand Down Expand Up @@ -235,7 +238,12 @@ def set_keepalive_token(self, keepAliveToken=DEFAULT_KEEPALIVE_TOKEN):
# keepalive (cannot be modified), but implementation uses
# NO_KEEP_ALIVE value as it does not change the query msgpack and
# xls does not support keepalive
if self.response in [
# Queries with destination only supports NO_KEEP_ALIVE
if self.destination is not None:
self.keepAliveToken = NO_KEEPALIVE_TOKEN
if keepAliveToken not in [NO_KEEPALIVE_TOKEN, DEFAULT_KEEPALIVE_TOKEN]:
logging.warning(ERROR_MSGS["no_keepalive_for_destination"])
elif self.response in [
"json",
"json/compact",
"json/simple",
Expand All @@ -254,7 +262,6 @@ def set_keepalive_token(self, keepAliveToken=DEFAULT_KEEPALIVE_TOKEN):
self.keepAliveToken = NO_KEEPALIVE_TOKEN
return True


class Client:
"""
The Devo search rest api main class
Expand Down Expand Up @@ -441,6 +448,7 @@ def query(
:param limit: Max number of rows
:param offset: start of needle for query
:param comment: comment for query
:param ip_as_string: whether to recive IP types as strings
:return: Result of the query (dict) or Iterator object
"""
dates = self._generate_dates(dates)
Expand Down Expand Up @@ -755,18 +763,10 @@ def _generate_pragmas(self, comment=None):

return str_pragmas

def get_jobs(self, job_type=None, name=None):
def get_jobs(self):
"""Get list of jobs by type and name, default All
:param job_type: category of jobs
:param name: name of jobs
:return: json"""
plus = (
""
if not job_type
else "/{}".format(job_type if not name else "{}/{}".format(job_type, name))
)

return self._call_jobs("{}{}{}".format(self.address[0], "/search/jobs", plus))
return self._call_jobs("{}{}".format(self.address[0], "/search/jobs"))

def get_job(self, job_id):
"""Get all info of job
Expand Down
2 changes: 1 addition & 1 deletion devo/api/scripts/client_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def configure(args):
"""
Load CLI configuration
:param args: args from files, launch vars, etc
:return: Clien t API Object and Config values in array
:return: Client API Object and Config values in array
"""
config = Configuration()
try:
Expand Down
11 changes: 7 additions & 4 deletions devo/common/dates/dateoperations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"""A collection of allowed operations on date parsing"""

from datetime import datetime as dt
import zoneinfo
UTC = zoneinfo.ZoneInfo("UTC")

from datetime import timedelta

from .dateutils import to_millis, trunc_time, trunc_time_minute
Expand Down Expand Up @@ -60,31 +63,31 @@ def now():
Return current millis in UTC
:return: Millis
"""
return to_millis(dt.utcnow())
return to_millis(dt.now(UTC))


def now_without_ms():
"""
Return current millis in UTC
:return: Millis
"""
return to_millis(trunc_time_minute(dt.utcnow()))
return to_millis(trunc_time_minute(dt.now(UTC)))


def today():
"""
Return current millis with the time truncated to 00:00:00
:return: Millis
"""
return to_millis(trunc_time(dt.utcnow()))
return to_millis(trunc_time(dt.now(UTC)))


def yesterday():
"""
Return millis from yesterday with time truncated to 00:00:00
:return: Millis
"""
return to_millis(trunc_time(dt.utcnow()) - timedelta(days=1))
return to_millis(trunc_time(dt.now(UTC)) - timedelta(days=1))


def parse_functions():
Expand Down
9 changes: 7 additions & 2 deletions devo/common/dates/dateutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
"""Utils for format and trunc dates."""

from datetime import datetime as dt
import zoneinfo
UTC = zoneinfo.ZoneInfo("UTC")


def to_millis(date):
Expand All @@ -10,7 +12,10 @@ def to_millis(date):
:param date: Date for parse to millis
:return: Millis from the date
"""
return int((date - dt.utcfromtimestamp(0)).total_seconds() * 1000)
# Verify whether param has timezone, if not set the default UTC one
if date.tzinfo is None:
date = date.replace(tzinfo=UTC)
return int((date - dt.fromtimestamp(0, UTC)).total_seconds() * 1000)


def trunc_time(date):
Expand Down Expand Up @@ -50,4 +55,4 @@ def get_timestamp():
Generate current timestamp
:return:
"""
return to_millis(dt.utcnow())
return to_millis(dt.now(UTC))
30 changes: 21 additions & 9 deletions devo/sender/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from ssl import SSLWantReadError, SSLWantWriteError
from threading import Thread, Lock, Event
from typing import Optional, Callable
import warnings

import pem
from _socket import SHUT_WR
Expand Down Expand Up @@ -74,6 +75,7 @@ def __str__(self):
RAW_SENDING_ERROR = ("Error sending raw event: %s",)
CLOSING_ERROR = "Error closing connection"
FLUSHING_BUFFER_ERROR = "Error flushing buffer"
ERROR_AFTER_TIMEOUT = "Timeout reached"


class DevoSenderException(Exception):
Expand Down Expand Up @@ -593,8 +595,6 @@ def __connect_ssl(self):
context = ssl.create_default_context(cafile=self._sender_config.chain)
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3
context.options |= ssl.OP_NO_TLSv1
context.options |= ssl.OP_NO_TLSv1_1
context.minimum_version = ssl.TLSVersion.TLSv1_2
context.maximum_version = ssl.TLSVersion.TLSv1_3

Expand All @@ -614,9 +614,16 @@ def __connect_ssl(self):
self.socket, server_hostname=self._sender_config.address[0]
)
else:
self.socket = ssl.wrap_socket(
self.socket, ssl_version=ssl.PROTOCOL_TLS, cert_reqs=ssl.CERT_NONE
)
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3
context.minimum_version = ssl.TLSVersion.TLSv1_2
context.maximum_version = ssl.TLSVersion.TLSv1_3
self.logger.warning("One or more of CA certificate, private or public certificate is not provided"
" and TLS unsecure connection is established")
self.socket = context.wrap_socket(self.socket)

self.socket.connect(self._sender_config.address)
self.last_message = int(time.time())
Expand All @@ -643,17 +650,19 @@ def info(self, msg):
"""
self.send(tag=self.logging.get("tag"), msg=msg)

# TODO: Deprecated
# TODO: Deprecated, to remove in next mayor version
def set_sec_level(self, sec_level=None):
"""
Set sec_level of SSL Context:

:param sec_level: sec_level value
:return
"""
warnings.warn("This function is deprecated and it will be removed in future versions",
DeprecationWarning, stacklevel=2)
self._sender_config.sec_level = sec_level

# TODO: Deprecated
# TODO: Deprecated, to remove in next mayor version
def set_verify_mode(self, verify_mode=None):
"""
Set verify_mode of SSL Context:
Expand All @@ -665,16 +674,20 @@ def set_verify_mode(self, verify_mode=None):
:param verify_mode: verify mode value
:return
"""
warnings.warn("This function is deprecated and it will be removed in future versions",
DeprecationWarning, stacklevel=2)
self._sender_config.verify_mode = verify_mode

# TODO: Deprecated
# TODO: Deprecated, to remove in next mayor version
def set_check_hostname(self, check_hostname=True):
"""
Set check_hostname of SSL Context:

:param check_hostname: check_hostname value. Default True
:return
"""
warnings.warn("This function is deprecated and it will be removed in future versions",
DeprecationWarning, stacklevel=2)
self._sender_config.check_hostname = check_hostname

def buffer_size(self, size=19500):
Expand Down Expand Up @@ -1093,7 +1106,6 @@ def for_logging(config=None, con_type=None, tag=None, level=None):
:param con_type: type of connection
:param tag: tag for the table
:param level: level of logger
:param formatter: log formatter
:return: Sender object
"""
con = Sender(config=config, con_type=con_type)
Expand Down
3 changes: 3 additions & 0 deletions devo/sender/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ def field_to_str(field, escape_quotes=False):
"""
Convert one value to STR, cleaning it
:param field: field to clean
:param escape_quotes: whether to escape quotes in response
:return:
"""
return ",%s" % Lookup.clean_field(field, escape_quotes)
Expand All @@ -402,6 +403,7 @@ def process_fields(fields=None, key_index=None, escape_quotes=False):
Method to convert list with one row/fields to STR to send
:param fields: fields list
:param key_index: index of key in fields
:param escape_quotes: whether to escape quotes in response
:return:
"""
# First the key
Expand All @@ -417,6 +419,7 @@ def clean_field(field=None, escape_quotes=False):
"""
Strip and quotechar the fields
:param str field: field for clean
:param escape_quotes: whether to escape quotes in response
:return str: cleaned field
"""
if not isinstance(field, (str, bytes)):
Expand Down
1 change: 1 addition & 0 deletions docs/api/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ Client support several modes for supporting this mechanism. The mode is set up i
* `json`, `json/compact`, `json/simple` and `json/simple/compact` token is always `b' '` (four utf-8 spaces chars)
* For `csv` and `tsv` token is the custom `str` set as parameter
* `msgpack` and `xls` do not support this mode
* Queries using `destination` functionality does not support keep alive. NO_KEEP_ALIVE is forced

| Response mode | default mode | `NO_KEEPALIVE_TOKEN` | `DEFAULT_KEEPALIVE_TOKEN` | `EMPTY_EVENT_KEEPALIVE_TOKEN` | Custom keep alive token |
|---------------------|---------------------------|----------------------|---------------------------|-------------------------------|------------------------------|
Expand Down
5 changes: 3 additions & 2 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
stopit==1.1.2
msgpack~=1.0.8
responses~=0.25.3
pipdeptree~=2.23.0
pytest~=8.2.2
pytest-cov~=5.0.0
mock==5.1.0
mock==5.1.0
pebble==5.0.7
pytest-timeout~=2.3.1
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
click==8.1.7
PyYAML==6.0.1
PyYAML~=6.0.1
requests~=2.32
pem~=21.2.0
pyopenssl~=24.2.1
Expand Down
Loading
Loading