qase-python-commons 3.3.0__tar.gz → 3.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of qase-python-commons might be problematic. Click here for more details.
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/PKG-INFO +2 -2
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/pyproject.toml +1 -1
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/client/api_v1_client.py +3 -1
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/client/api_v2_client.py +3 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/core.py +6 -1
- qase_python_commons-3.3.2/src/qase/commons/util/__init__.py +9 -0
- qase_python_commons-3.3.2/src/qase/commons/util/host_data.py +140 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/PKG-INFO +2 -2
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/SOURCES.txt +2 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/README.md +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/setup.cfg +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/__init__.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/client/base_api_client.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/config.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/exceptions/reporter.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/loader.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/logger.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/__init__.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/attachment.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/basemodel.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/api.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/batch.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/connection.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/framework.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/plan.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/qaseconfig.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/report.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/run.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/testops.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/relation.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/result.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/run.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/runtime.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/step.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/profilers/__init__.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/profilers/db.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/profilers/network.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/profilers/sleep.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/__init__.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/report.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/testops.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/utils.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/validators/base.py +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/dependency_links.txt +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/requires.txt +0 -0
- {qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: qase-python-commons
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: A library for Qase TestOps and Qase Report
|
|
5
5
|
Author-email: Qase Team <support@qase.io>
|
|
6
6
|
Project-URL: Homepage, https://github.com/qase-tms/qase-python/tree/main/qase-python-commons
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qase-python-commons"
|
|
7
|
-
version = "3.3.
|
|
7
|
+
version = "3.3.2"
|
|
8
8
|
description = "A library for Qase TestOps and Qase Report"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{name = "Qase Team", email = "support@qase.io"}]
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/client/api_v1_client.py
RENAMED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
1
2
|
from typing import Dict, Union
|
|
2
3
|
|
|
3
4
|
import certifi
|
|
@@ -99,7 +100,8 @@ class ApiV1Client(BaseApiClient):
|
|
|
99
100
|
description=description,
|
|
100
101
|
environment_id=(int(environment_id) if environment_id else None),
|
|
101
102
|
plan_id=(int(plan_id) if plan_id else plan_id),
|
|
102
|
-
is_autotest=True
|
|
103
|
+
is_autotest=True,
|
|
104
|
+
start_time=datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
|
|
103
105
|
)
|
|
104
106
|
self.logger.log_debug(f"Creating test run with parameters: {kwargs}")
|
|
105
107
|
try:
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/client/api_v2_client.py
RENAMED
|
@@ -78,6 +78,7 @@ class ApiV2Client(ApiV1Client):
|
|
|
78
78
|
signature=result.signature,
|
|
79
79
|
testops_id=result.get_testops_id(),
|
|
80
80
|
execution=ResultExecution(status=result.execution.status, duration=result.execution.duration,
|
|
81
|
+
start_time=result.execution.start_time, end_time=result.execution.end_time,
|
|
81
82
|
stacktrace=result.execution.stacktrace, thread=result.execution.thread),
|
|
82
83
|
fields=ResultCreateFields.from_dict(result.fields),
|
|
83
84
|
attachments=[attach.hash for attach in attached],
|
|
@@ -112,6 +113,8 @@ class ApiV2Client(ApiV1Client):
|
|
|
112
113
|
prepared_step = {'execution': {}, 'data': {}, 'steps': []}
|
|
113
114
|
prepared_step['execution']['status'] = ResultStepStatus(step.execution.status)
|
|
114
115
|
prepared_step['execution']['duration'] = step.execution.duration
|
|
116
|
+
prepared_step['execution']['start_time'] = step.execution.start_time
|
|
117
|
+
prepared_step['execution']['end_time'] = step.execution.end_time
|
|
115
118
|
|
|
116
119
|
if step.step_type == StepType.TEXT:
|
|
117
120
|
prepared_step['data']['action'] = step.data.action
|
|
@@ -10,6 +10,8 @@ from ..models import InternalResult, Result, Attachment, Runtime
|
|
|
10
10
|
from ..models.config.qaseconfig import Mode
|
|
11
11
|
from typing import Union, List
|
|
12
12
|
|
|
13
|
+
from ..util import get_host_info
|
|
14
|
+
|
|
13
15
|
"""
|
|
14
16
|
CoreReporter is a facade for all reporters and it is used to initialize and manage them.
|
|
15
17
|
It is also used to pass configuration and logger to reporters, handle fallback logic and error handling.
|
|
@@ -17,7 +19,7 @@ from typing import Union, List
|
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
class QaseCoreReporter:
|
|
20
|
-
def __init__(self, config: ConfigManager):
|
|
22
|
+
def __init__(self, config: ConfigManager, framework: Union[str, None] = None, reporter_name: Union[str, None] = None):
|
|
21
23
|
config.validate_config()
|
|
22
24
|
self.config = config.config
|
|
23
25
|
self.logger = Logger(self.config.debug)
|
|
@@ -30,6 +32,9 @@ class QaseCoreReporter:
|
|
|
30
32
|
|
|
31
33
|
self.logger.log_debug(f"Config: {self.config}")
|
|
32
34
|
|
|
35
|
+
host_data = get_host_info(framework, reporter_name)
|
|
36
|
+
self.logger.log_debug(f"Host data: {host_data}")
|
|
37
|
+
|
|
33
38
|
# Reading reporter mode from config file
|
|
34
39
|
mode = self.config.mode
|
|
35
40
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import subprocess
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
from typing import Optional, Dict
|
|
8
|
+
|
|
9
|
+
HostData = Dict[str, str]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def exec_command(command: str, default_value: str = "") -> str:
|
|
13
|
+
try:
|
|
14
|
+
result = subprocess.run(
|
|
15
|
+
command,
|
|
16
|
+
shell=True,
|
|
17
|
+
check=True,
|
|
18
|
+
stdout=subprocess.PIPE,
|
|
19
|
+
stderr=subprocess.PIPE,
|
|
20
|
+
text=True
|
|
21
|
+
)
|
|
22
|
+
return result.stdout.strip()
|
|
23
|
+
except Exception as e:
|
|
24
|
+
print(f"Error executing command '{command}': {e}", file=sys.stderr)
|
|
25
|
+
return default_value
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_detailed_os_info() -> str:
|
|
29
|
+
system = platform.system().lower()
|
|
30
|
+
try:
|
|
31
|
+
if system == "windows":
|
|
32
|
+
return exec_command("ver")
|
|
33
|
+
elif system == "darwin":
|
|
34
|
+
return exec_command("sw_vers -productVersion")
|
|
35
|
+
else:
|
|
36
|
+
try:
|
|
37
|
+
if os.path.exists("/etc/os-release"):
|
|
38
|
+
with open("/etc/os-release", "r") as f:
|
|
39
|
+
os_release = f.read()
|
|
40
|
+
match = re.search(r'PRETTY_NAME="(.+?)"', os_release)
|
|
41
|
+
if match:
|
|
42
|
+
return match.group(1)
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
return platform.release()
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print(f"Error getting detailed OS info: {e}", file=sys.stderr)
|
|
48
|
+
return platform.release()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_package_version(package_name: Optional[str]) -> Optional[str]:
|
|
52
|
+
if not package_name:
|
|
53
|
+
return ""
|
|
54
|
+
try:
|
|
55
|
+
pip_output = exec_command(f"pip show {package_name}")
|
|
56
|
+
if pip_output:
|
|
57
|
+
version_match = re.search(r'Version:\s*(\S+)', pip_output)
|
|
58
|
+
if version_match:
|
|
59
|
+
return version_match.group(1)
|
|
60
|
+
pip_list_output = exec_command("pip list --format=json")
|
|
61
|
+
if pip_list_output:
|
|
62
|
+
packages = json.loads(pip_list_output)
|
|
63
|
+
for pkg in packages:
|
|
64
|
+
if pkg.get("name", "").lower() == package_name.lower():
|
|
65
|
+
return pkg.get("version")
|
|
66
|
+
try:
|
|
67
|
+
import importlib.metadata
|
|
68
|
+
return importlib.metadata.version(package_name)
|
|
69
|
+
except (ImportError, importlib.metadata.PackageNotFoundError):
|
|
70
|
+
pass
|
|
71
|
+
return ""
|
|
72
|
+
except Exception as e:
|
|
73
|
+
print(f"Error getting version for package {package_name}: {e}", file=sys.stderr)
|
|
74
|
+
return ""
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def find_package_in_requirements(package_name: Optional[str]) -> Optional[str]:
|
|
78
|
+
if not package_name:
|
|
79
|
+
return ""
|
|
80
|
+
try:
|
|
81
|
+
possible_req_files = ['requirements.txt', 'requirements/base.txt', 'requirements/dev.txt']
|
|
82
|
+
for req_file in possible_req_files:
|
|
83
|
+
if os.path.exists(req_file):
|
|
84
|
+
with open(req_file, 'r') as f:
|
|
85
|
+
for line in f:
|
|
86
|
+
if line.startswith(package_name):
|
|
87
|
+
version_match = re.search(r'[=<>~]{1,2}([\d.]+)', line)
|
|
88
|
+
if version_match:
|
|
89
|
+
return version_match.group(1)
|
|
90
|
+
return ""
|
|
91
|
+
except Exception as e:
|
|
92
|
+
print(f"Error reading requirements for {package_name}: {e}", file=sys.stderr)
|
|
93
|
+
return ""
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def get_host_info(framework: Optional[str], reporter_name: Optional[str]) -> HostData:
|
|
97
|
+
try:
|
|
98
|
+
python_version = platform.python_version()
|
|
99
|
+
pip_version = exec_command("pip --version")
|
|
100
|
+
if pip_version:
|
|
101
|
+
pip_match = re.search(r'pip\s+(\S+)', pip_version)
|
|
102
|
+
pip_version = pip_match.group(1) if pip_match else ""
|
|
103
|
+
framework_version = get_package_version(framework) or find_package_in_requirements(framework) or ""
|
|
104
|
+
reporter_version = get_package_version(reporter_name) or find_package_in_requirements(reporter_name) or ""
|
|
105
|
+
commons_version = get_package_version("qase-python-commons") or find_package_in_requirements(
|
|
106
|
+
"qase-python-commons") or ""
|
|
107
|
+
api_client_version_1 = get_package_version("qase-api-client") or find_package_in_requirements(
|
|
108
|
+
"qase-api-client") or ""
|
|
109
|
+
api_client_version_2 = get_package_version("qase-api-v2-client") or find_package_in_requirements(
|
|
110
|
+
"qase-api-v2-client") or ""
|
|
111
|
+
return {
|
|
112
|
+
"system": platform.system().lower(),
|
|
113
|
+
"machineName": platform.node(),
|
|
114
|
+
"release": platform.release(),
|
|
115
|
+
"version": get_detailed_os_info(),
|
|
116
|
+
"arch": platform.machine(),
|
|
117
|
+
"python": python_version,
|
|
118
|
+
"pip": pip_version,
|
|
119
|
+
"framework": framework_version,
|
|
120
|
+
"reporter": reporter_version,
|
|
121
|
+
"commons": commons_version,
|
|
122
|
+
"apiClientV1": api_client_version_1,
|
|
123
|
+
"apiClientV2": api_client_version_2
|
|
124
|
+
}
|
|
125
|
+
except Exception as e:
|
|
126
|
+
print(f"Error getting host info: {e}", file=sys.stderr)
|
|
127
|
+
return {
|
|
128
|
+
"system": platform.system().lower(),
|
|
129
|
+
"machineName": platform.node(),
|
|
130
|
+
"release": platform.release(),
|
|
131
|
+
"version": "",
|
|
132
|
+
"arch": platform.machine(),
|
|
133
|
+
"python": "",
|
|
134
|
+
"pip": "",
|
|
135
|
+
"framework": "",
|
|
136
|
+
"reporter": "",
|
|
137
|
+
"commons": "",
|
|
138
|
+
"apiClientV1": "",
|
|
139
|
+
"apiClientV2": ""
|
|
140
|
+
}
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: qase-python-commons
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: A library for Qase TestOps and Qase Report
|
|
5
5
|
Author-email: Qase Team <support@qase.io>
|
|
6
6
|
Project-URL: Homepage, https://github.com/qase-tms/qase-python/tree/main/qase-python-commons
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase_python_commons.egg-info/SOURCES.txt
RENAMED
|
@@ -34,6 +34,8 @@ src/qase/commons/reporters/__init__.py
|
|
|
34
34
|
src/qase/commons/reporters/core.py
|
|
35
35
|
src/qase/commons/reporters/report.py
|
|
36
36
|
src/qase/commons/reporters/testops.py
|
|
37
|
+
src/qase/commons/util/__init__.py
|
|
38
|
+
src/qase/commons/util/host_data.py
|
|
37
39
|
src/qase/commons/validators/base.py
|
|
38
40
|
src/qase_python_commons.egg-info/PKG-INFO
|
|
39
41
|
src/qase_python_commons.egg-info/SOURCES.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/client/base_api_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/exceptions/reporter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/attachment.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/basemodel.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/api.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/batch.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/connection.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/framework.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/plan.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/qaseconfig.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/report.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/run.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/models/config/testops.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/profilers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/profilers/network.py
RENAMED
|
File without changes
|
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/__init__.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/report.py
RENAMED
|
File without changes
|
{qase_python_commons-3.3.0 → qase_python_commons-3.3.2}/src/qase/commons/reporters/testops.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|