Skip to content
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
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
default_language_version:
python: python3.10
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

## [Unreleased]
### Added
- Attribute key length and number truncation, by @HardNorth
- Binary character replacement in basic text fields, by @HardNorth

## [5.7.0]
### Added
- Official `Python 3.14` support, by @HardNorth
- Custom log level support in `RPLogHandler` class, by @HardNorth
### Removed
- `Python 3.7` support, by @HardNorth
- `Python 3.8` support, by @HardNorth
- Deprecated `log_manager.py` module, by @HardNorth

## [5.6.7]
Expand Down
84 changes: 48 additions & 36 deletions reportportal_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ class _ClientOptions(TypedDict, total=False):
launch_uuid_print: bool
print_output: OutputType
truncate_attributes: bool
truncate_fields: bool
replace_binary_chars: bool
launch_name_length_limit: int
item_name_length_limit: int
launch_description_length_limit: int
item_description_length_limit: int
log_batch_size: int
log_batch_payload_limit: int
# Async client specific parameters
Expand All @@ -80,42 +86,48 @@ def create_client(
) -> Optional[RP]:
"""Create and ReportPortal Client based on the type and arguments provided.

:param client_type: Type of the Client to create.
:param endpoint: Endpoint of the ReportPortal service.
:param project: Project name to report to.
:param api_key: Authorization API key.
:param oauth_uri: OAuth 2.0 token endpoint URI (for OAuth authentication).
:param oauth_username: Username for OAuth 2.0 authentication.
:param oauth_password: Password for OAuth 2.0 authentication.
:param oauth_client_id: OAuth 2.0 client ID.
:param oauth_client_secret: OAuth 2.0 client secret (optional).
:param oauth_scope: OAuth 2.0 scope (optional).
:param launch_uuid: A launch UUID to use instead of starting own one.
:param is_skipped_an_issue: Option to mark skipped tests as not 'To Investigate' items on the server
side.
:param verify_ssl: Option to skip ssl verification.
:param retries: Number of retry attempts to make in case of connection / server
errors.
:param max_pool_size: Option to set the maximum number of connections to save the pool.
:param http_timeout : A float in seconds for connect and read timeout. Use a Tuple to
specific connect and read separately.
:param mode: Launch mode, all Launches started by the client will be in that mode.
:param launch_uuid_print: Print Launch UUID into passed TextIO or by default to stdout.
:param print_output: Set output stream for Launch UUID printing.
:param truncate_attributes: Truncate test item attributes to default maximum length.
:param log_batch_size: Option to set the maximum number of logs that can be processed in one
batch.
:param log_batch_payload_limit: Maximum size in bytes of logs that can be processed in one batch.
:param keepalive_timeout: For Async Clients only. Maximum amount of idle time in seconds before
force connection closing.
:param task_timeout: For Async Threaded and Batched Clients only. Time limit in seconds for a
Task processing.
:param shutdown_timeout: For Async Threaded and Batched Clients only. Time limit in seconds for
shutting down internal Tasks.
:param trigger_num: For Async Batched Client only. Number of tasks which triggers Task batch
execution.
:param trigger_interval: For Async Batched Client only. Time limit which triggers Task batch
execution.
:param client_type: Type of the Client to create.
:param endpoint: Endpoint of the ReportPortal service.
:param project: Project name to report to.
:param api_key: Authorization API key.
:param oauth_uri: OAuth 2.0 token endpoint URI (for OAuth authentication).
:param oauth_username: Username for OAuth 2.0 authentication.
:param oauth_password: Password for OAuth 2.0 authentication.
:param oauth_client_id: OAuth 2.0 client ID.
:param oauth_client_secret: OAuth 2.0 client secret (optional).
:param oauth_scope: OAuth 2.0 scope (optional).
:param launch_uuid: A launch UUID to use instead of starting own one.
:param is_skipped_an_issue: Option to mark skipped tests as not 'To Investigate' items on the server
side.
:param verify_ssl: Option to skip ssl verification.
:param retries: Number of retry attempts to make in case of connection / server
errors.
:param max_pool_size: Option to set the maximum number of connections to save the pool.
:param http_timeout: A float in seconds for connect and read timeout. Use a Tuple to
specific connect and read separately.
:param mode: Launch mode, all Launches started by the client will be in that mode.
:param launch_uuid_print: Print Launch UUID into passed TextIO or by default to stdout.
:param print_output: Set output stream for Launch UUID printing.
:param truncate_attributes: Truncate test item attributes to default maximum length.
:param truncate_fields: Truncate request fields to configured limits.
:param replace_binary_chars: Toggle replacement of basic binary characters with \ufffd char.
:param launch_name_length_limit: Maximum allowed launch name length.
:param item_name_length_limit: Maximum allowed test item name length.
:param launch_description_length_limit: Maximum allowed launch description length.
:param item_description_length_limit: Maximum allowed test item description length.
:param log_batch_size: Option to set the maximum number of logs that can be processed in one
batch.
:param log_batch_payload_limit: Maximum size in bytes of logs that can be processed in one batch.
:param keepalive_timeout: For Async Clients only. Maximum amount of idle time in seconds before
force connection closing.
:param task_timeout: For Async Threaded and Batched Clients only. Time limit in seconds for a
Task processing.
:param shutdown_timeout: For Async Threaded and Batched Clients only. Time limit in seconds for
shutting down internal Tasks.
:param trigger_num: For Async Batched Client only. Number of tasks which triggers Task batch
execution.
:param trigger_interval: For Async Batched Client only. Time limit which triggers Task batch
execution.
:return: ReportPortal Client instance.
"""
my_kwargs = kwargs.copy()
Expand Down
16 changes: 13 additions & 3 deletions reportportal_client/_internal/aio/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,25 @@
import sys
import time
from asyncio import Future
from typing import Any, Awaitable, Coroutine, Generator, Generic, Optional, TypeVar, Union
from typing import Any, Coroutine, Generator, Generic, Optional, TypeVar, Union

from reportportal_client.aio.tasks import BlockingOperationError, Task

if sys.version_info >= (3, 10):
from typing import TypeAlias
else:
from typing_extensions import TypeAlias

_T = TypeVar("_T")

DEFAULT_TASK_TRIGGER_NUM: int = 10
DEFAULT_TASK_TRIGGER_INTERVAL: float = 1.0

if sys.version_info >= (3, 12):
_TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, Any]
else:
_TaskCompatibleCoro: TypeAlias = Union[Generator[Optional[Future[object]], None, Any], Coroutine[Any, Any, Any]]


class BatchedTask(Generic[_T], Task[_T]):
"""Represents a Task which uses the current Thread to execute itself."""
Expand All @@ -34,7 +44,7 @@ class BatchedTask(Generic[_T], Task[_T]):

def __init__(
self,
coro: Union[Generator[Future, None, _T], Awaitable[_T]],
coro: _TaskCompatibleCoro,
*,
loop: asyncio.AbstractEventLoop,
name: Optional[str] = None,
Expand Down Expand Up @@ -68,7 +78,7 @@ class ThreadedTask(Generic[_T], Task[_T]):

def __init__(
self,
coro: Union[Generator[Future, None, _T], Awaitable[_T]],
coro: _TaskCompatibleCoro,
wait_timeout: float,
*,
loop: asyncio.AbstractEventLoop,
Expand Down
14 changes: 7 additions & 7 deletions reportportal_client/_internal/logs/batcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@

logger = logging.getLogger(__name__)

T_co = TypeVar("T_co", bound="RPRequestLog", covariant=True)
LogRequestType = TypeVar("LogRequestType", bound=RPRequestLog)


class LogBatcher(Generic[T_co]):
class LogBatcher(Generic[LogRequestType]):
"""Log packaging class to automate compiling separate Log entries into log batches.

The class accepts the maximum number of log entries in desired batches and maximum batch size to conform
Expand All @@ -35,7 +35,7 @@ class LogBatcher(Generic[T_co]):
entry_num: int
payload_limit: int
_lock: threading.Lock
_batch: list[T_co]
_batch: list[LogRequestType]
_payload_size: int

def __init__(self, entry_num=MAX_LOG_BATCH_SIZE, payload_limit=MAX_LOG_BATCH_PAYLOAD_SIZE) -> None:
Expand All @@ -50,7 +50,7 @@ def __init__(self, entry_num=MAX_LOG_BATCH_SIZE, payload_limit=MAX_LOG_BATCH_PAY
self._batch = []
self._payload_size = 0

def _append(self, size: int, log_req: RPRequestLog) -> Optional[list[RPRequestLog]]:
def _append(self, size: int, log_req: LogRequestType) -> Optional[list[LogRequestType]]:
with self._lock:
if self._payload_size + size >= self.payload_limit:
if len(self._batch) > 0:
Expand All @@ -74,17 +74,17 @@ def append(self, log_req: RPRequestLog) -> Optional[list[RPRequestLog]]:
:param log_req: log request object
:return: a batch or None
"""
return self._append(log_req.multipart_size, log_req)
return self._append(log_req.multipart_size, log_req) # type: ignore

async def append_async(self, log_req: AsyncRPRequestLog) -> Optional[list[AsyncRPRequestLog]]:
"""Add a log request object to internal batch and return the batch if it's full.

:param log_req: log request object
:return: a batch or None
"""
return self._append(await log_req.multipart_size, log_req)
return self._append(await log_req.multipart_size, log_req) # type: ignore

def flush(self) -> Optional[list[T_co]]:
def flush(self) -> Optional[list[LogRequestType]]:
"""Immediately return everything what's left in the internal batch.

:return: a batch or None
Expand Down
2 changes: 1 addition & 1 deletion reportportal_client/_internal/services/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _get_client_info() -> tuple[str, str]:
:return: ('reportportal-client', '5.0.4')
"""
name, version = get_package_parameters("reportportal-client", ["name", "version"])
return name, version
return name or "None", version or "None"


def _get_platform_info() -> str:
Expand Down
1 change: 1 addition & 0 deletions reportportal_client/_internal/static/defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
10000: "DEBUG",
5000: "TRACE",
}
DEFAULT_LOG_LEVEL = RP_LOG_LEVELS[40000]


class _PresenceSentinel:
Expand Down
Loading
Loading