qase-python-commons 4.1.6__tar.gz → 4.1.8__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.
Files changed (50) hide show
  1. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/PKG-INFO +1 -1
  2. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/pyproject.toml +1 -1
  3. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/client/api_v2_client.py +81 -2
  4. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/reporters/core.py +10 -1
  5. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/reporters/testops.py +2 -7
  6. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/util/host_data.py +20 -13
  7. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase_python_commons.egg-info/PKG-INFO +1 -1
  8. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/README.md +0 -0
  9. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/setup.cfg +0 -0
  10. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/__init__.py +0 -0
  11. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/__init__.py +0 -0
  12. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/client/api_v1_client.py +0 -0
  13. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/client/base_api_client.py +0 -0
  14. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/config.py +0 -0
  15. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/exceptions/reporter.py +0 -0
  16. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/loader.py +0 -0
  17. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/logger.py +0 -0
  18. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/__init__.py +0 -0
  19. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/attachment.py +0 -0
  20. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/basemodel.py +0 -0
  21. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/api.py +0 -0
  22. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/batch.py +0 -0
  23. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/connection.py +0 -0
  24. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/framework.py +0 -0
  25. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/plan.py +0 -0
  26. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/qaseconfig.py +0 -0
  27. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/report.py +0 -0
  28. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/run.py +0 -0
  29. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/config/testops.py +0 -0
  30. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/external_link.py +0 -0
  31. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/relation.py +0 -0
  32. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/result.py +0 -0
  33. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/run.py +0 -0
  34. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/runtime.py +0 -0
  35. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/models/step.py +0 -0
  36. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/profilers/__init__.py +0 -0
  37. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/profilers/db.py +0 -0
  38. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/profilers/network.py +0 -0
  39. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/profilers/sleep.py +0 -0
  40. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/reporters/__init__.py +0 -0
  41. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/reporters/report.py +0 -0
  42. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/status_mapping/__init__.py +0 -0
  43. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/status_mapping/status_mapping.py +0 -0
  44. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/util/__init__.py +0 -0
  45. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/utils.py +0 -0
  46. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase/commons/validators/base.py +0 -0
  47. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase_python_commons.egg-info/SOURCES.txt +0 -0
  48. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase_python_commons.egg-info/dependency_links.txt +0 -0
  49. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase_python_commons.egg-info/requires.txt +0 -0
  50. {qase_python_commons-4.1.6 → qase_python_commons-4.1.8}/src/qase_python_commons.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qase-python-commons
3
- Version: 4.1.6
3
+ Version: 4.1.8
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 = "4.1.6"
7
+ version = "4.1.8"
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"}]
@@ -1,4 +1,4 @@
1
- from typing import Dict
1
+ from typing import Dict, Union, Optional
2
2
 
3
3
  import certifi
4
4
  from qase.api_client_v2 import ResultsApi, ResultCreateFields
@@ -20,11 +20,16 @@ from ..models.config.framework import Video, Trace
20
20
  from ..models import Attachment, Result
21
21
  from ..models.config.qaseconfig import QaseConfig
22
22
  from ..models.step import StepType, Step
23
+ from ..util.host_data import HostData
23
24
 
24
25
 
25
26
  class ApiV2Client(ApiV1Client):
26
- def __init__(self, config: QaseConfig, logger: Logger):
27
+ def __init__(self, config: QaseConfig, logger: Logger, host_data: Optional[HostData] = None,
28
+ framework: Union[str, None] = None, reporter_name: Union[str, None] = None):
27
29
  ApiV1Client.__init__(self, config, logger)
30
+ self.host_data = host_data or {}
31
+ self.framework = framework
32
+ self.reporter_name = reporter_name
28
33
 
29
34
  try:
30
35
  self.logger.log_debug("Preparing API V2 client")
@@ -40,10 +45,84 @@ class ApiV2Client(ApiV1Client):
40
45
  self.web = f'https://{host}'
41
46
 
42
47
  self.client_v2 = ApiClient(configuration)
48
+
49
+ # Add X-Client and X-Platform headers
50
+ self._add_client_headers()
51
+
43
52
  self.logger.log_debug("API V2 client prepared")
44
53
  except Exception as e:
45
54
  self.logger.log(f"Error at preparing API V2 client: {e}", "error")
46
55
  raise ReporterException(e)
56
+
57
+ def _add_client_headers(self):
58
+ """Add X-Client and X-Platform headers to API client"""
59
+ try:
60
+ # Use host_data passed from Core reporter
61
+ host_data = self.host_data
62
+
63
+ # Use framework and reporter_name for names in X-Client header
64
+ framework = self.framework
65
+ reporter_name = self.reporter_name
66
+
67
+ # Build X-Client header
68
+ # Format: reporter=qase-pytest;reporter_version=v1.0.0;framework=pytest;framework_version=7.0.0;client_version_v1=v1.0.0;client_version_v2=v2.0.0;core_version=v1.5.0
69
+ x_client_parts = []
70
+
71
+ if reporter_name:
72
+ x_client_parts.append(f"reporter={reporter_name}")
73
+ reporter_version = host_data.get('reporter', '')
74
+ if reporter_version:
75
+ x_client_parts.append(f"reporter_version=v{reporter_version}")
76
+
77
+ if framework:
78
+ x_client_parts.append(f"framework={framework}")
79
+ framework_version = host_data.get('framework', '')
80
+ if framework_version:
81
+ x_client_parts.append(f"framework_version={framework_version}")
82
+
83
+ client_v1_version = host_data.get('apiClientV1', '')
84
+ if client_v1_version:
85
+ x_client_parts.append(f"client_version_v1=v{client_v1_version}")
86
+
87
+ client_v2_version = host_data.get('apiClientV2', '')
88
+ if client_v2_version:
89
+ x_client_parts.append(f"client_version_v2=v{client_v2_version}")
90
+
91
+ core_version = host_data.get('commons', '')
92
+ if core_version:
93
+ x_client_parts.append(f"core_version=v{core_version}")
94
+
95
+ x_client = ";".join(x_client_parts)
96
+
97
+ # Build X-Platform header
98
+ # Format: os=Linux;arch=aarch64;python=3.9.0;pip=22.0.0
99
+ x_platform_parts = []
100
+
101
+ os_name = host_data.get('system', '')
102
+ if os_name:
103
+ x_platform_parts.append(f"os={os_name}")
104
+
105
+ arch = host_data.get('arch', '')
106
+ if arch:
107
+ x_platform_parts.append(f"arch={arch}")
108
+
109
+ python_version = host_data.get('python', '')
110
+ if python_version:
111
+ x_platform_parts.append(f"python={python_version}")
112
+
113
+ pip_version = host_data.get('pip', '')
114
+ if pip_version:
115
+ x_platform_parts.append(f"pip={pip_version}")
116
+
117
+ x_platform = ";".join(x_platform_parts)
118
+
119
+ # Add headers to client
120
+ if x_client:
121
+ self.client_v2.default_headers['X-Client'] = x_client
122
+ if x_platform:
123
+ self.client_v2.default_headers['X-Platform'] = x_platform
124
+ except Exception as e:
125
+ self.logger.log(f"Error adding client headers: {e}", "error")
47
126
 
48
127
  def send_results(self, project_code: str, run_id: str, results: []) -> None:
49
128
  api_results = ResultsApi(self.client_v2)
@@ -43,13 +43,22 @@ class QaseCoreReporter:
43
43
  host_data = get_host_info(framework, reporter_name)
44
44
  self.logger.log_debug(f"Host data: {host_data}")
45
45
 
46
+ # Store framework and reporter_name for passing to reporters
47
+ self.framework = framework
48
+ self.reporter_name = reporter_name
49
+ self.host_data = host_data
50
+
46
51
  # Reading reporter mode from config file
47
52
  mode = self.config.mode
48
53
 
49
54
  if mode == Mode.testops:
50
55
  try:
51
56
  self._load_testops_plan()
52
- self.reporter = QaseTestOps(config=self.config, logger=self.logger)
57
+ # Create API client with host_data for headers
58
+ from ..client.api_v2_client import ApiV2Client
59
+ api_client = ApiV2Client(self.config, self.logger, host_data=host_data,
60
+ framework=framework, reporter_name=reporter_name)
61
+ self.reporter = QaseTestOps(config=self.config, logger=self.logger, client=api_client)
53
62
  except Exception as e:
54
63
  self.logger.log('Failed to initialize TestOps reporter. Using fallback.', 'info')
55
64
  self.logger.log(e, 'error')
@@ -4,7 +4,6 @@ import urllib.parse
4
4
  from datetime import datetime
5
5
  from typing import List, Union
6
6
  from .. import Logger, ReporterException
7
- from ..client.api_v2_client import ApiV2Client
8
7
  from ..client.base_api_client import BaseApiClient
9
8
  from ..models import Result
10
9
  from ..models.config.qaseconfig import QaseConfig
@@ -15,12 +14,11 @@ DEFAULT_THREAD_COUNT = 4
15
14
 
16
15
  class QaseTestOps:
17
16
 
18
- def __init__(self, config: QaseConfig, logger: Logger) -> None:
17
+ def __init__(self, config: QaseConfig, logger: Logger, client: BaseApiClient) -> None:
19
18
  self.config = config
20
19
  self.logger = logger
21
20
  self.__baseUrl = self.__get_host(config.testops.api.host)
22
-
23
- self.client = self._prepare_client()
21
+ self.client = client
24
22
 
25
23
  run_id = self.config.testops.run.id
26
24
  plan_id = self.config.testops.plan.id
@@ -68,9 +66,6 @@ class QaseTestOps:
68
66
  """Verify that project exists in TestOps"""
69
67
  self.client.get_project(self.project_code)
70
68
 
71
- def _prepare_client(self) -> BaseApiClient:
72
- return ApiV2Client(self.config, self.logger)
73
-
74
69
  def _send_results_threaded(self, results):
75
70
  try:
76
71
  self.client.send_results(self.project_code, self.run_id, results)
@@ -93,26 +93,33 @@ def find_package_in_requirements(package_name: Optional[str]) -> Optional[str]:
93
93
  return ""
94
94
 
95
95
 
96
+ def remove_version_prefix(version: str) -> str:
97
+ """Remove 'v' prefix from version string if present."""
98
+ if version and version.startswith('v'):
99
+ return version[1:]
100
+ return version
101
+
102
+
96
103
  def get_host_info(framework: Optional[str], reporter_name: Optional[str]) -> HostData:
97
104
  try:
98
- python_version = platform.python_version()
105
+ python_version = remove_version_prefix(platform.python_version())
99
106
  pip_version = exec_command("pip --version")
100
107
  if pip_version:
101
108
  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 ""
109
+ pip_version = remove_version_prefix(pip_match.group(1) if pip_match else "")
110
+ framework_version = remove_version_prefix(get_package_version(framework) or find_package_in_requirements(framework) or "")
111
+ reporter_version = remove_version_prefix(get_package_version(reporter_name) or find_package_in_requirements(reporter_name) or "")
112
+ commons_version = remove_version_prefix(get_package_version("qase-python-commons") or find_package_in_requirements(
113
+ "qase-python-commons") or "")
114
+ api_client_version_1 = remove_version_prefix(get_package_version("qase-api-client") or find_package_in_requirements(
115
+ "qase-api-client") or "")
116
+ api_client_version_2 = remove_version_prefix(get_package_version("qase-api-v2-client") or find_package_in_requirements(
117
+ "qase-api-v2-client") or "")
111
118
  return {
112
119
  "system": platform.system().lower(),
113
120
  "machineName": platform.node(),
114
- "release": platform.release(),
115
- "version": get_detailed_os_info(),
121
+ "release": remove_version_prefix(platform.release()),
122
+ "version": remove_version_prefix(get_detailed_os_info()),
116
123
  "arch": platform.machine(),
117
124
  "python": python_version,
118
125
  "pip": pip_version,
@@ -127,7 +134,7 @@ def get_host_info(framework: Optional[str], reporter_name: Optional[str]) -> Hos
127
134
  return {
128
135
  "system": platform.system().lower(),
129
136
  "machineName": platform.node(),
130
- "release": platform.release(),
137
+ "release": remove_version_prefix(platform.release()),
131
138
  "version": "",
132
139
  "arch": platform.machine(),
133
140
  "python": "",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qase-python-commons
3
- Version: 4.1.6
3
+ Version: 4.1.8
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