Skip to content

Commit c29541d

Browse files
Merge pull request #7 from WPSemantix/task/migrate-up-to-python-3.12.0
Task/migrate up to python 3.12.0
2 parents 0d80ec5 + 5009ac5 commit c29541d

File tree

14 files changed

+504
-35
lines changed

14 files changed

+504
-35
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Test Python package new version
2+
on:
3+
push:
4+
branches: [ "main" ]
5+
pull_request:
6+
branches: [ "main" ]
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
python-version: ["3.9", "3.10", "3.11", "3.12"]
14+
steps:
15+
- uses: actions/checkout@v4
16+
- name: Set up Python ${{ matrix.python-version }}
17+
uses: actions/setup-python@v3
18+
with:
19+
python-version: ${{ matrix.python-version }}
20+
- name: Install Linux dependencies
21+
run: |
22+
sudo apt-get update
23+
sudo apt-get install -y \
24+
gcc \
25+
libkrb5-dev \
26+
libsasl2-dev \
27+
python3-dev \
28+
python3-all-dev
29+
- name: Update pip version
30+
run: |
31+
python -m pip install --upgrade pip
32+
- name: Install dependencies
33+
run: |
34+
pip install -r test/requirements.txt
35+
- name: Build new version of the package
36+
run: |
37+
python -m build
38+
- name: Install the new version of the package
39+
run: |
40+
pip install dist/*.tar.gz
41+
- name: Test with pytest
42+
env:
43+
HOSTNAME: ${{ secrets.HOSTNAME }}
44+
PORT: ${{ secrets.PORT }}
45+
PROTOCOL: ${{ secrets.PROTOCOL }}
46+
ONTOLOGY: ${{ secrets.ONTOLOGY }}
47+
USERNAME: ${{ secrets.USERNAME }}
48+
PASSWORD: ${{ secrets.PASSWORD }}
49+
CONNECT_ARGS: ${{ secrets.CONNECT_ARGS }}
50+
run: |
51+
pytest

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ coverage.xml
5151
*.py,cover
5252
.hypothesis/
5353
.pytest_cache/
54-
test.py
55-
test/
54+
test/env*
55+
test/.python-version
56+
test/.env
5657

5758
# Translations
5859
*.mo

MANIFEST.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
include examples/*
1+
include examples/*
2+
include thrift/transport/THttpClient.py

README.md

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
![Timbr logo](https://timbr.ai/wp-content/uploads/2023/06/timbr-ai-l-5-226x60-1.png)
1+
![Timbr logo](https://timbr.ai/wp-content/uploads/2025/01/logotimbrai230125.png)
22

33
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B50508%2Fgithub.com%2FWPSemantix%2Ftimbr_python_SQLAlchemy.svg?type=shield&issueType=license)](https://app.fossa.com/projects/custom%2B50508%2Fgithub.com%2FWPSemantix%2Ftimbr_python_SQLAlchemy?ref=badge_shield&issueType=license)
44
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B50508%2Fgithub.com%2FWPSemantix%2Ftimbr_python_SQLAlchemy.svg?type=shield&issueType=security)](https://app.fossa.com/projects/custom%2B50508%2Fgithub.com%2FWPSemantix%2Ftimbr_python_SQLAlchemy?ref=badge_shield&issueType=security)
55

6-
[![Python 3.7.13](https://img.shields.io/badge/python-3.7.13+-blue.svg)](https://www.python.org/downloads/release/python-3713/)
7-
[![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-3820/)
86
[![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-3921/)
7+
[![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-31017/)
8+
[![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31112/)
9+
[![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/)
910

1011
[![PypiVersion](https://img.shields.io/pypi/v/pytimbr-sqla.svg)](https://badge.fury.io/py/pytimbr-sqla)
1112

@@ -14,7 +15,7 @@ This project is a python connector to timbr using SQLAlchemy.
1415

1516
## Dependencies
1617
- Access to a timbr-server
17-
- Python from 3.7.13 or newer
18+
- Python from 3.9.13 or newer
1819
- Support SQLAlchemy 1.4.36 or newer but not version 2.x yet.
1920
- For <b>Linux</b> based machines only install those dependencies first:
2021
- gcc
@@ -27,10 +28,9 @@ This project is a python connector to timbr using SQLAlchemy.
2728
- Ubuntu example:
2829
- apt install gcc, heimdal-dev, krb5, python-devel, python-dev, python-all-dev, libsasl2-dev
2930

30-
3131
## Installation
3232
- Install as clone repository:
33-
- Install Python: https://www.python.org/downloads/release/python-3713/
33+
- Install Python: https://www.python.org/downloads/release/python-3913/
3434
- Run the following command to install the Python dependencies: `pip install -r requirements.txt`
3535

3636
- Install using pip and git:
@@ -39,15 +39,6 @@ This project is a python connector to timbr using SQLAlchemy.
3939
- Install using pip:
4040
- `pip install pytimbr-sqla`
4141

42-
## Known issues
43-
If you encounter a problem installing `PyHive` with sasl dependencies on windows, install the following wheel (for 64bit Windows) by running:
44-
45-
`pip install https://download.lfd.uci.edu/pythonlibs/archived/cp37/sasl-0.3.1-cp37-cp37m-win_amd64.whl`
46-
47-
For Python 3.9:
48-
49-
`pip install https://download.lfd.uci.edu/pythonlibs/archived/sasl-0.3.1-cp39-cp39-win_amd64.whl`
50-
5142
## Sample usage
5243
- For an example of how to use the Python SQLAlchemy connector for timbr, follow this [example file](examples/example.py)
5344
- For an example of how to use the Python SQLAlchemy connector with 'PyHive' as async query for timbr, follow this [example file](examples/pyhive_async_example.py)

requirements.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
future==0.18.3
2-
python-dateutil==2.8.2
3-
sasl>=0.2.1
4-
thrift>=0.13.0
5-
thrift_sasl>=0.1.0
1+
future==1.0.0
2+
python-dateutil==2.9.0
3+
ldap3
4+
thrift==0.21.0
5+
thrift_sasl==0.4.3
66
pure-sasl>=0.6.2
77
sqlalchemy>=1.4.36,<2.0.0
8-
requests_kerberos>=0.12.0
8+
requests_kerberos==0.15.0

setup.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,28 @@
55

66
setuptools.setup(
77
name='pytimbr_sqla',
8-
version='1.0.7',
8+
version='2.0.0',
99
author='timbr',
1010
author_email='[email protected]',
1111
description='Timbr Python SQLAlchemy connector',
1212
long_description=long_description,
1313
long_description_content_type="text/markdown",
1414
url='https://github.com/WPSemantix/timbr_python_SQLAlchemy',
15-
download_url = 'https://github.com/WPSemantix/timbr_python_SQLAlchemy/archive/refs/tags/v1.0.7.tar.gz',
15+
download_url = 'https://github.com/WPSemantix/timbr_python_SQLAlchemy/archive/refs/tags/v2.0.0.tar.gz',
1616
project_urls={
1717
"Bug Tracker": "https://github.com/WPSemantix/timbr_python_SQLAlchemy/issues"
1818
},
1919
license='MIT',
20-
packages=['pytimbr_sqla', 'TCLIService'],
20+
packages=['pytimbr_sqla', 'TCLIService', 'thrift', 'thrift.transport'],
2121
install_requires=[
22-
'future',
23-
'python-dateutil',
24-
'sasl>=0.2.1',
25-
'thrift>=0.13.0',
26-
'thrift_sasl>=0.1.0',
22+
'future==1.0.0',
23+
'python-dateutil==2.9.0',
24+
'ldap3',
25+
'thrift_sasl==0.4.3',
2726
'pure-sasl>=0.6.2',
2827
'sqlalchemy>=1.4.36,<2.0.0',
29-
'requests_kerberos>=0.12.0',
28+
'requests_kerberos==0.15.0',
29+
'pyhive==0.7.0',
3030
],
3131
extras_require={},
3232
package_data={},
@@ -64,9 +64,10 @@
6464
'Topic :: Software Development :: Build Tools',
6565
'License :: OSI Approved :: MIT License',
6666
'Programming Language :: Python :: 3',
67-
'Programming Language :: Python :: 3.7',
68-
'Programming Language :: Python :: 3.8',
6967
'Programming Language :: Python :: 3.9',
68+
'Programming Language :: Python :: 3.10',
69+
'Programming Language :: Python :: 3.11',
70+
'Programming Language :: Python :: 3.12',
7071
],
7172
entry_points={
7273
'sqlalchemy.dialects': [

test/conftest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import os
2+
import json
3+
import pytest
4+
from dotenv import load_dotenv
5+
6+
# Load .env file if it exists
7+
load_dotenv(override=True)
8+
9+
# Global fixture to load config values
10+
@pytest.fixture(scope="session")
11+
def test_config():
12+
return {
13+
"hostname": os.getenv("HOSTNAME"),
14+
"port": os.getenv("PORT"),
15+
"protocol": os.getenv("PROTOCOL"),
16+
"ontology": os.getenv("ONTOLOGY"),
17+
"username": os.getenv("USERNAME"),
18+
"password": os.getenv("PASSWORD"),
19+
"connect_args": json.loads(os.getenv("CONNECT_ARGS", "{}"))
20+
}

test/requirements.txt

422 Bytes
Binary file not shown.

test/test_hive_dialect.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import pytest
2+
from utils import get_connection_uri_using_hive_dialect, run_query_using_hive_dialect
3+
4+
def create_engine_and_run_query(config, is_async=False):
5+
"""
6+
Creates a SQLAlchemy engine and runs a query using the Hive dialect.
7+
"""
8+
uri = get_connection_uri_using_hive_dialect(
9+
hostname=config['hostname'],
10+
port=config['port'],
11+
protocol=config['protocol'],
12+
ontology=config['ontology'],
13+
username=config['username'],
14+
password=config['password']
15+
)
16+
return run_query_using_hive_dialect(
17+
uri,
18+
"SHOW CONCEPTS",
19+
config['connect_args'],
20+
is_async,
21+
)
22+
23+
def test_run_sync_query(test_config):
24+
results_obj = create_engine_and_run_query(test_config, is_async=False)
25+
results_data = results_obj["results"]
26+
results_headers = results_obj["headers"]
27+
28+
assert results_obj is not None, "Query did not return any results"
29+
assert len(results_data) > 0, "Query returned no rows"
30+
assert len(results_headers) > 0, "Query returned no columns"
31+
assert all(len(row) == len(results_headers) for row in results_data), "Row length does not match header length"
32+
33+
def test_run_async_query(test_config):
34+
results_obj = create_engine_and_run_query(test_config, is_async=True)
35+
results_data = results_obj["results"]
36+
results_headers = results_obj["headers"]
37+
38+
assert results_obj is not None, "Query did not return any results"
39+
assert len(results_data) > 0, "Query returned no rows"
40+
assert len(results_headers) > 0, "Query returned no columns"
41+
assert all(len(row) == len(results_headers) for row in results_data), "Row length does not match header length"

test/test_timbr_dialect.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import pytest
2+
from utils import run_query_using_timbr_dialect, get_connection_uri_using_timbr_dialect
3+
4+
def test_run_query(test_config):
5+
uri = get_connection_uri_using_timbr_dialect(
6+
hostname=test_config['hostname'],
7+
port=test_config['port'],
8+
protocol=test_config['protocol'],
9+
ontology=test_config['ontology'],
10+
username=test_config['username'],
11+
password=test_config['password']
12+
)
13+
results_obj = run_query_using_timbr_dialect(uri, "SHOW CONCEPTS", connect_args=test_config['connect_args'])
14+
results_data = results_obj["results"]
15+
results_headers = results_obj["headers"]
16+
17+
assert results_obj is not None, "Query did not return any results"
18+
assert len(results_data) > 0, "Query returned no rows"
19+
assert len(results_headers) > 0, "Query returned no columns"
20+
assert all(len(row) == len(results_headers) for row in results_data), "Row length does not match header length"

0 commit comments

Comments
 (0)