Skip to content

Commit b30fbca

Browse files
Merge branch 'main' into SNOW-2043816-Kerberos-Proxy-Auth-Python
2 parents e1f149e + 56e524e commit b30fbca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1411
-357
lines changed

.github/workflows/build_test.yml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ jobs:
173173
- name: Run tests
174174
# To run a single test on GHA use the below command:
175175
# run: python -m tox run -e `echo py${PYTHON_VERSION/\./}-single-ci | sed 's/ /,/g'`
176-
run: python -m tox run -e `echo py${PYTHON_VERSION/\./}-{extras,unit,integ,pandas,sso}-ci | sed 's/ /,/g'`
176+
run: python -m tox run -e `echo py${PYTHON_VERSION/\./}-{extras,unit-parallel,integ-parallel,pandas-parallel,sso}-ci | sed 's/ /,/g'`
177177

178178
env:
179179
PYTHON_VERSION: ${{ matrix.python-version }}
@@ -193,6 +193,12 @@ jobs:
193193
path: |
194194
.tox/.coverage
195195
.tox/coverage.xml
196+
- uses: actions/upload-artifact@v4
197+
with:
198+
include-hidden-files: true
199+
name: junit_${{ matrix.os.download_name }}-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
200+
path: |
201+
.tox/junit.*.xml
196202
197203
test-olddriver:
198204
name: Old Driver Test ${{ matrix.os.download_name }}-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
@@ -307,6 +313,12 @@ jobs:
307313
path: |
308314
.coverage
309315
coverage.xml
316+
- uses: actions/upload-artifact@v4
317+
with:
318+
include-hidden-files: true
319+
name: junit_linux-fips-3.9-${{ matrix.cloud-provider }}
320+
path: |
321+
junit.*.xml
310322
311323
test-lambda:
312324
name: Test Lambda linux-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
@@ -354,6 +366,12 @@ jobs:
354366
path: |
355367
.coverage.py${{ env.shortver }}-lambda-ci
356368
junit.py${{ env.shortver }}-lambda-ci-dev.xml
369+
- uses: actions/upload-artifact@v4
370+
with:
371+
include-hidden-files: true
372+
name: junit_linux-lambda-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
373+
path: |
374+
junit.py${{ env.shortver }}-lambda-ci-dev.xml
357375
358376
combine-coverage:
359377
if: ${{ success() || failure() }}
@@ -388,6 +406,21 @@ jobs:
388406
dst_file = dst_dir / ".coverage.{}".format(src_file.parent.name[9:])
389407
print("{} copy to {}".format(src_file, dst_file))
390408
shutil.copy(str(src_file), str(dst_file))'
409+
- name: Collect all JUnit XML files to one dir
410+
run: |
411+
python -c '
412+
from pathlib import Path
413+
import shutil
414+
415+
src_dir = Path("artifacts")
416+
dst_dir = Path(".") / "junit_results"
417+
dst_dir.mkdir()
418+
# Collect all JUnit XML files with different naming patterns
419+
for pattern in ["*/junit.*.xml", "*/junit.py*-lambda-ci-dev.xml"]:
420+
for src_file in src_dir.glob(pattern):
421+
dst_file = dst_dir / src_file.name
422+
print("{} copy to {}".format(src_file, dst_file))
423+
shutil.copy(str(src_file), str(dst_file))'
391424
- name: Combine coverages
392425
run: python -m tox run -e coverage
393426
- name: Publish html coverage
@@ -406,3 +439,9 @@ jobs:
406439
with:
407440
files: .tox/coverage.xml
408441
token: ${{ secrets.CODECOV_TOKEN }}
442+
- name: Upload test results to Codecov
443+
if: ${{ !cancelled() }}
444+
uses: codecov/test-results-action@v1
445+
with:
446+
token: ${{ secrets.CODECOV_TOKEN }}
447+
files: junit_results/junit.*.xml
Binary file not shown.

DESCRIPTION.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,27 @@ https://docs.snowflake.com/
77
Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
88

99
# Release Notes
10-
- v3.16(TBD)
10+
- v3.17(TBD)
1111
- Bumped numpy dependency from <2.1.0 to <=2.2.4
1212
- Added Windows support for Python 3.13.
1313
- Add `bulk_upload_chunks` parameter to `write_pandas` function. Setting this parameter to True changes the behaviour of write_pandas function to first write all the data chunks to the local disk and then perform the wildcard upload of the chunks folder to the stage. In default behaviour the chunks are being saved, uploaded and deleted one by one.
1414
- Add `headers_customizers` parameter to the `connect` function. Setting this parameter allows enriching outgoing request headers using a list of customizers. Only header enrichment is supported — modifying query parameters or overwriting the existing headers is not allowed.
1515
- Added support for new authentication mechanism PAT with external session ID
1616

17-
- v3.15.1(May 20, 2025)
17+
- v3.16.1(TBD)
18+
- Added in-band OCSP exception telemetry.
19+
- Added in-band HTTP exception telemetry.
20+
- Fixed a bug where timezoned timestamps fetched as pandas.DataFrame or pyarrow.Table would overflow for the sake of unnecessary precision. In the case where an overflow cannot be prevented a clear error will be raised now.
21+
22+
- v3.16.0(July 04,2025)
23+
- Bumped numpy dependency from <2.1.0 to <=2.2.4.
24+
- Added Windows support for Python 3.13.
25+
- Added `bulk_upload_chunks` parameter to `write_pandas` function. Setting this parameter to True changes the behaviour of write_pandas function to first write all the data chunks to the local disk and then perform the wildcard upload of the chunks folder to the stage. In default behaviour the chunks are being saved, uploaded and deleted one by one.
26+
- Added support for new authentication mechanism PAT with external session ID.
27+
- Added `client_fetch_use_mp` parameter that enables multiprocessed fetching of result batches.
1828
- Added basic arrow support for Interval types.
19-
- Fix `write_pandas` special characters usage in the location name.
20-
- Fix usage of `use_virtual_url` when building the location for gcs storage client.
21-
- Bind cryptography to <=44.0.3 to avoid issues with 45.0.0.
29+
- Fixed `write_pandas` special characters usage in the location name.
30+
- Fixed usage of `use_virtual_url` when building the location for gcs storage client.
2231
- Added support for Snowflake OAuth for local applications.
2332

2433
- v3.15.0(Apr 29,2025)

ci/test_authentication.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ docker run \
2323
-v $(cd $THIS_DIR/.. && pwd):/mnt/host \
2424
-v $WORKSPACE:/mnt/workspace \
2525
--rm \
26-
nexus.int.snowflakecomputing.com:8086/docker/snowdrivers-test-external-browser-python:1 \
26+
nexus.int.snowflakecomputing.com:8086/docker/snowdrivers-test-external-browser-python:2 \
2727
"/mnt/host/ci/container/test_authentication.sh"

ci/test_fips.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ curl https://repo1.maven.org/maven2/org/wiremock/wiremock-standalone/3.11.0/wire
1414
python3 -m venv fips_env
1515
source fips_env/bin/activate
1616
pip install -U setuptools pip
17+
18+
# Install pytest-xdist for parallel execution
19+
pip install pytest-xdist
20+
1721
pip install "${CONNECTOR_WHL}[pandas,secure-local-storage,development]"
1822

1923
echo "!!! Environment description !!!"
@@ -24,6 +28,8 @@ python -c "from cryptography.hazmat.backends.openssl import backend;print('Cryp
2428
pip freeze
2529

2630
cd $CONNECTOR_DIR
27-
pytest -vvv --cov=snowflake.connector --cov-report=xml:coverage.xml test
31+
32+
# Run tests in parallel using pytest-xdist
33+
pytest -n auto -vvv --cov=snowflake.connector --cov-report=xml:coverage.xml test
2834

2935
deactivate

ci/test_linux.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ else
4040
echo "[Info] Testing with ${PYTHON_VERSION}"
4141
SHORT_VERSION=$(python3.10 -c "print('${PYTHON_VERSION}'.replace('.', ''))")
4242
CONNECTOR_WHL=$(ls $CONNECTOR_DIR/dist/snowflake_connector_python*cp${SHORT_VERSION}*manylinux2014*.whl | sort -r | head -n 1)
43-
TEST_LIST=`echo py${PYTHON_VERSION/\./}-{unit,integ,pandas,sso}-ci | sed 's/ /,/g'`
43+
TEST_LIST=`echo py${PYTHON_VERSION/\./}-{unit-parallel,integ,pandas-parallel,sso}-ci | sed 's/ /,/g'`
4444
TEST_ENVLIST=fix_lint,$TEST_LIST,py${PYTHON_VERSION/\./}-coverage
4545
echo "[Info] Running tox for ${TEST_ENVLIST}"
4646

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ install_requires =
4747
boto3>=1.24
4848
botocore>=1.24
4949
cffi>=1.9,<2.0.0
50-
cryptography>=3.1.0,<=44.0.3
50+
cryptography>=3.1.0
5151
pyOpenSSL>=22.0.0,<26.0.0
5252
pyjwt<3.0.0
5353
pytz

src/snowflake/connector/_utils.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ class TempObjectType(Enum):
3232

3333
REQUEST_ID_STATEMENT_PARAM_NAME = "requestId"
3434

35+
# Default server side cap on Degree of Parallelism for file transfer
36+
# This default value is set to 2^30 (~ 10^9), such that it will not
37+
# throttle regular sessions.
38+
_DEFAULT_VALUE_SERVER_DOP_CAP_FOR_FILE_TRANSFER = 1 << 30
39+
# Variable name of server DoP cap for file transfer
40+
_VARIABLE_NAME_SERVER_DOP_CAP_FOR_FILE_TRANSFER = (
41+
"snowflake_server_dop_cap_for_file_transfer"
42+
)
43+
3544

3645
def generate_random_alphanumeric(length: int = 10) -> str:
3746
return "".join(choice(ALPHANUMERIC) for _ in range(length))
@@ -60,6 +69,15 @@ def is_uuid4(str_or_uuid: str | UUID) -> bool:
6069
return uuid_str == str_or_uuid
6170

6271

72+
def _snowflake_max_parallelism_for_file_transfer(connection):
73+
"""Returns the server side cap on max parallelism for file transfer for the given connection."""
74+
return getattr(
75+
connection,
76+
f"_{_VARIABLE_NAME_SERVER_DOP_CAP_FOR_FILE_TRANSFER}",
77+
_DEFAULT_VALUE_SERVER_DOP_CAP_FOR_FILE_TRANSFER,
78+
)
79+
80+
6381
class _TrackedQueryCancellationTimer(Timer):
6482
def __init__(self, interval, function, args=None, kwargs=None):
6583
super().__init__(interval, function, args, kwargs)

src/snowflake/connector/auth/by_plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class AuthType(Enum):
5050
ID_TOKEN = "ID_TOKEN"
5151
USR_PWD_MFA = "USERNAME_PASSWORD_MFA"
5252
OKTA = "OKTA"
53-
PAT = "PROGRAMMATIC_ACCESS_TOKEN'"
53+
PAT = "PROGRAMMATIC_ACCESS_TOKEN"
5454
NO_AUTH = "NO_AUTH"
5555
WORKLOAD_IDENTITY = "WORKLOAD_IDENTITY"
5656
PAT_WITH_EXTERNAL_SESSION = "PAT_WITH_EXTERNAL_SESSION"

src/snowflake/connector/auth/pat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(self, pat_token: str, **kwargs) -> None:
1313
super().__init__(**kwargs)
1414
self._pat_token: str | None = pat_token
1515

16+
@property
1617
def type_(self) -> AuthType:
1718
return AuthType.PAT
1819

0 commit comments

Comments
 (0)