influxdb3-python 0.14.0__tar.gz → 0.15.0__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.
- {influxdb3_python-0.14.0/influxdb3_python.egg-info → influxdb3_python-0.15.0}/PKG-INFO +1 -1
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0/influxdb3_python.egg-info}/PKG-INFO +1 -1
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/__init__.py +27 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/version.py +1 -1
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_influxdb_client_3.py +58 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_influxdb_client_3_integration.py +13 -40
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/basic_ssl_example.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/batching_example.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/cloud_dedicated_query.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/cloud_dedicated_write.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/config.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/flight_options_example.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/handle_http_error.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/handle_query_error.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/pandas_write.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/query_async.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/Examples/query_type.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/LICENSE +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/README.md +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb3_python.egg-info/SOURCES.txt +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb3_python.egg-info/dependency_links.txt +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb3_python.egg-info/requires.txt +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb3_python.egg-info/top_level.txt +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/exceptions/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/exceptions/exceptions.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/py.typed +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/query/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/query/query_api.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/read_file.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/_sync/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/_sync/api_client.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/_sync/rest.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/_base.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/influxdb_client.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/logging_handler.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/util/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/util/date_utils.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/util/date_utils_pandas.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/util/helpers.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/util/multiprocessing_helper.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/warnings.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/write/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/write/dataframe_serializer.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/write/point.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/write/polars_dataframe_serializer.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/write/retry.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/write_api.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/configuration.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/domain/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/domain/write_precision.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/domain/write_precision_converter.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/extras.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/rest.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/service/__init__.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/service/_base_service.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/service/signin_service.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/service/signout_service.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/service/write_service.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/pyproject.toml +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/setup.cfg +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/setup.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_api_client.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_dataframe_serializer.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_date_helper.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_deep_merge.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_merge_options.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_point.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_polars.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_query.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_write_file.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_write_local_server.py +0 -0
- {influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_write_precision_converter.py +0 -0
|
@@ -467,6 +467,33 @@ class InfluxDBClient3:
|
|
|
467
467
|
except ArrowException as e:
|
|
468
468
|
raise InfluxDB3ClientQueryError(f"Error while executing query: {e}")
|
|
469
469
|
|
|
470
|
+
def get_server_version(self) -> str:
|
|
471
|
+
"""
|
|
472
|
+
Get the version of the connected InfluxDB server.
|
|
473
|
+
|
|
474
|
+
This method makes a ping request to the server and extracts the version information
|
|
475
|
+
from either the response headers or response body.
|
|
476
|
+
|
|
477
|
+
:return: The version string of the InfluxDB server.
|
|
478
|
+
:rtype: str
|
|
479
|
+
"""
|
|
480
|
+
version = None
|
|
481
|
+
(resp_body, _, header) = self._client.api_client.call_api(
|
|
482
|
+
resource_path="/ping",
|
|
483
|
+
method="GET",
|
|
484
|
+
response_type=object
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
for key, value in header.items():
|
|
488
|
+
if key.lower() == "x-influxdb-version":
|
|
489
|
+
version = value
|
|
490
|
+
break
|
|
491
|
+
|
|
492
|
+
if version is None and isinstance(resp_body, dict):
|
|
493
|
+
version = resp_body['version']
|
|
494
|
+
|
|
495
|
+
return version
|
|
496
|
+
|
|
470
497
|
def close(self):
|
|
471
498
|
"""Close the client and clean up resources."""
|
|
472
499
|
self._write_api.close()
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
import re
|
|
1
2
|
import unittest
|
|
2
3
|
from unittest.mock import patch
|
|
3
4
|
|
|
5
|
+
from pytest_httpserver import HTTPServer
|
|
6
|
+
|
|
4
7
|
from influxdb_client_3 import InfluxDBClient3, WritePrecision, DefaultWriteOptions, Point, WriteOptions, WriteType
|
|
5
8
|
from influxdb_client_3.exceptions import InfluxDB3ClientQueryError
|
|
9
|
+
from influxdb_client_3.write_client.rest import ApiException
|
|
6
10
|
from tests.util import asyncio_run
|
|
7
11
|
from tests.util.mocks import ConstantFlightServer, ConstantData, ErrorFlightServer
|
|
8
12
|
|
|
9
13
|
|
|
14
|
+
def http_server():
|
|
15
|
+
httpserver = HTTPServer()
|
|
16
|
+
httpserver.start()
|
|
17
|
+
return httpserver
|
|
18
|
+
|
|
19
|
+
|
|
10
20
|
class TestInfluxDBClient3(unittest.TestCase):
|
|
11
21
|
|
|
12
22
|
@patch('influxdb_client_3._InfluxDBClient')
|
|
@@ -22,6 +32,11 @@ class TestInfluxDBClient3(unittest.TestCase):
|
|
|
22
32
|
database="my_db",
|
|
23
33
|
token="my_token"
|
|
24
34
|
)
|
|
35
|
+
self.http_server = http_server()
|
|
36
|
+
|
|
37
|
+
def tearDown(self):
|
|
38
|
+
if self.http_server is not None:
|
|
39
|
+
self.http_server.stop()
|
|
25
40
|
|
|
26
41
|
def test_init(self):
|
|
27
42
|
self.assertEqual(self.client._org, "my_org")
|
|
@@ -226,6 +241,49 @@ class TestInfluxDBClient3(unittest.TestCase):
|
|
|
226
241
|
await c.query_async("SELECT * FROM my_data")
|
|
227
242
|
self.assertIn("Error while executing query", str(err.exception))
|
|
228
243
|
|
|
244
|
+
def test_get_version_header_success(self):
|
|
245
|
+
server = self.http_server
|
|
246
|
+
server.expect_request(re.compile(".*")).respond_with_json(
|
|
247
|
+
headers={"X-Influxdb-Version": "1.8.2"},
|
|
248
|
+
response_json={"version": "3.0"}
|
|
249
|
+
)
|
|
250
|
+
version = InfluxDBClient3(
|
|
251
|
+
host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
|
|
252
|
+
).get_server_version()
|
|
253
|
+
assert version == "1.8.2"
|
|
254
|
+
|
|
255
|
+
def test_get_version_in_body_success(self):
|
|
256
|
+
server = self.http_server
|
|
257
|
+
server.expect_request('/ping').respond_with_json(
|
|
258
|
+
response_json={"version": "3.0"},
|
|
259
|
+
)
|
|
260
|
+
version = InfluxDBClient3(
|
|
261
|
+
host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
|
|
262
|
+
).get_server_version()
|
|
263
|
+
assert version == "3.0"
|
|
264
|
+
|
|
265
|
+
def test_get_version_empty(self):
|
|
266
|
+
server = self.http_server
|
|
267
|
+
server.expect_request("/ping").respond_with_data(
|
|
268
|
+
headers={"abc": "1.8.2"},
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
version = InfluxDBClient3(
|
|
272
|
+
host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
|
|
273
|
+
).get_server_version()
|
|
274
|
+
assert version is None
|
|
275
|
+
|
|
276
|
+
def test_get_version_fail(self):
|
|
277
|
+
server = self.http_server
|
|
278
|
+
server.expect_request("/ping").respond_with_json(
|
|
279
|
+
response_json={"error": "error"},
|
|
280
|
+
status=400
|
|
281
|
+
)
|
|
282
|
+
with self.assertRaises(ApiException):
|
|
283
|
+
InfluxDBClient3(
|
|
284
|
+
host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
|
|
285
|
+
).get_server_version()
|
|
286
|
+
|
|
229
287
|
|
|
230
288
|
if __name__ == '__main__':
|
|
231
289
|
unittest.main()
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/tests/test_influxdb_client_3_integration.py
RENAMED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
+
import pyarrow
|
|
4
|
+
import pytest
|
|
3
5
|
import random
|
|
4
6
|
import string
|
|
5
7
|
import time
|
|
6
8
|
import unittest
|
|
7
9
|
|
|
8
|
-
import pyarrow
|
|
9
|
-
import pytest
|
|
10
|
-
from influxdb_client_3.exceptions import InfluxDB3ClientQueryError, InfluxDBError
|
|
11
|
-
|
|
12
10
|
from influxdb_client_3 import InfluxDBClient3, write_client_options, WriteOptions
|
|
11
|
+
from influxdb_client_3.exceptions import InfluxDBError
|
|
13
12
|
from tests.util import asyncio_run, lp_to_py_object
|
|
14
13
|
|
|
15
14
|
|
|
@@ -64,30 +63,18 @@ class TestInfluxDBClient3Integration(unittest.TestCase):
|
|
|
64
63
|
test_id = time.time_ns()
|
|
65
64
|
with self.assertRaises(InfluxDBError) as err:
|
|
66
65
|
self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
|
|
67
|
-
self.assertEqual('
|
|
66
|
+
self.assertEqual('Authorization header was malformed, the request was not in the form of '
|
|
67
|
+
'\'Authorization: <auth-scheme> <token>\', supported auth-schemes are Bearer, Token and Basic',
|
|
68
|
+
err.exception.message) # Cloud
|
|
68
69
|
|
|
69
70
|
def test_auth_error_auth_scheme(self):
|
|
70
71
|
self.client = InfluxDBClient3(host=self.host, database=self.database, token=self.token, auth_scheme='Any')
|
|
71
72
|
test_id = time.time_ns()
|
|
72
73
|
with self.assertRaises(InfluxDBError) as err:
|
|
73
74
|
self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
|
|
74
|
-
self.assertEqual('
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.client = InfluxDBClient3(host=self.host, database=self.database, token=self.token)
|
|
78
|
-
with self.assertRaises(InfluxDBError) as err:
|
|
79
|
-
self.client.write("integration_test_python,type=used value=123.0,test_id=")
|
|
80
|
-
self.assertIn("Could not parse entire line. Found trailing content:", err.exception.message)
|
|
81
|
-
headers = err.exception.getheaders()
|
|
82
|
-
try:
|
|
83
|
-
self.assertIsNotNone(headers)
|
|
84
|
-
self.assertRegex(headers['trace-id'], '[0-9a-f]{16}')
|
|
85
|
-
self.assertEqual('false', headers['trace-sampled'])
|
|
86
|
-
self.assertIsNotNone(headers['Strict-Transport-Security'])
|
|
87
|
-
self.assertRegex(headers['X-Influxdb-Request-ID'], '[0-9a-f]+')
|
|
88
|
-
self.assertIsNotNone(headers['X-Influxdb-Build'])
|
|
89
|
-
except KeyError as ke:
|
|
90
|
-
self.fail(f'Header {ke} not found')
|
|
75
|
+
self.assertEqual('Authorization header was malformed, the request was not in the form of '
|
|
76
|
+
'\'Authorization: <auth-scheme> <token>\', supported auth-schemes are Bearer, Token and Basic',
|
|
77
|
+
err.exception.message) # Cloud
|
|
91
78
|
|
|
92
79
|
def test_batch_write_callbacks(self):
|
|
93
80
|
write_success = False
|
|
@@ -212,24 +199,6 @@ IdKIRUY6EyIVG+Z/nbuVqUlgnIWOMp0yg4RRC91zHy3Xvykf3Vai25H/jQpa6cbU
|
|
|
212
199
|
def remove_test_cert(self, cert_file):
|
|
213
200
|
os.remove(cert_file)
|
|
214
201
|
|
|
215
|
-
def test_queries_w_bad_cert(self):
|
|
216
|
-
cert_file = "test_cert.pem"
|
|
217
|
-
self.create_test_cert(cert_file)
|
|
218
|
-
with InfluxDBClient3(host=self.host,
|
|
219
|
-
database=self.database,
|
|
220
|
-
token=self.token,
|
|
221
|
-
verify_ssl=True,
|
|
222
|
-
ssl_ca_cert=cert_file,
|
|
223
|
-
debug=True) as client:
|
|
224
|
-
try:
|
|
225
|
-
query = "SELECT table_name FROM information_schema.tables"
|
|
226
|
-
client.query(query, mode="")
|
|
227
|
-
assert False, "query should throw SSL_ERROR"
|
|
228
|
-
except InfluxDB3ClientQueryError as fe:
|
|
229
|
-
assert str(fe).__contains__('SSL_ERROR_SSL')
|
|
230
|
-
finally:
|
|
231
|
-
self.remove_test_cert(cert_file)
|
|
232
|
-
|
|
233
202
|
def test_verify_ssl_false(self):
|
|
234
203
|
cert_file = "test_cert.pem"
|
|
235
204
|
self.create_test_cert(cert_file)
|
|
@@ -274,3 +243,7 @@ IdKIRUY6EyIVG+Z/nbuVqUlgnIWOMp0yg4RRC91zHy3Xvykf3Vai25H/jQpa6cbU
|
|
|
274
243
|
result_list = result.to_pylist()
|
|
275
244
|
for item in data:
|
|
276
245
|
assert lp_to_py_object(item) in result_list, f"original lp data \"{item}\" should be in result list"
|
|
246
|
+
|
|
247
|
+
def test_get_server_version(self):
|
|
248
|
+
version = self.client.get_server_version()
|
|
249
|
+
assert version is not None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb3_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/exceptions/__init__.py
RENAMED
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/exceptions/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/__init__.py
RENAMED
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/_sync/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/_sync/rest.py
RENAMED
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/client/_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{influxdb3_python-0.14.0 → influxdb3_python-0.15.0}/influxdb_client_3/write_client/extras.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|