oracle / python-oracledb

Python driver for Oracle Database conforming to the Python DB API 2.0 specification. This is the renamed, new major release of cx_Oracle
https://oracle.github.io/python-oracledb
Other
339 stars 67 forks source link

oracledb with cryptography >=43 cause error `DPY-3016: python-oracledb thin mode cannot be used because the cryptography package is not installed` #401

Closed zdenop closed 1 month ago

zdenop commented 1 month ago

Used versions

cryptography==43.0.1
pyinstaller==6.10.0
oracledb==2.4.1

oracledb.version: 2.4.1 platform.platform: Windows-10-10.0.19045-SP0 sys.maxsize > 2**32: True platform.python_version: 3.11.9

Error reproducing

Example code:

import os
from contextlib import suppress

import oracledb
from dotenv import load_dotenv

with suppress(BaseException):
    oracledb.init_oracle_client()
    print(f'Oracle client version: {oracledb.clientversion()}')

oracle_cnx = None
load_dotenv()

try:
    oracle_cnx = oracledb.connect(
        user=os.getenv('user'), password=os.getenv('pwd'), dsn=os.getenv('db')
    )
except oracledb.DatabaseError as err:
    (error,) = err.args
    print(error)

if oracle_cnx:
    print('Oracle connection works.')
    oracle_cnx.close()

app is created with: python -OO -m PyInstaller -F -c --noupx --noconfirm --hidden-import secrets --hidden-import asyncio --hidden-import uuid test.py

and run by: dist\test.exe

which produce: DPY-3016: python-oracledb thin mode cannot be used because the cryptography package is not installed

Workarounds

  1. Downgrade cryptography to 42.0.8. IMO this will cause dependency problems soon.
  2. set PATH=C:\oracle\ora122\client_x64\bin before running dist\test.exe. This will cause my app will not be usable on other computers and anyway it is not needed by cryptography==42.0.8
cjbj commented 1 month ago

Are you saying it works with 42.0.8 but not 43.0.1?

PS I'm not a Windows user.

zdenop commented 1 month ago

Are you saying it works with 42.0.8 but not 43.0.1?

Yes. Also it does not work with 43.0.0.

cjbj commented 1 month ago

@zdenop have you tried solutions along the lines of https://stackoverflow.com/a/77750988/4799035 ?

Possibly your fastest bet is to ask pyinstaller people how to appropriately handle the new version of cryptography.

zdenop commented 1 month ago

I am familiar with this SO post, but it was relevant for older versions of cryptography and PyInstaller.

Anyway I tried update my build command to python -OO -m PyInstaller -F -c --noupx --noconfirm --hidden-import secrets --hidden-import asyncio --hidden-import uuid --hidden-import, but it did not help.

I will try to open issue at PyInstaller, but from my user perspective: error is coming from oracledb and it seems like error message is not correct (cryptography is installed). App is miss something that is located in oracle client directory (see point 2. in Workarounds - I am not able identify what...)

cjbj commented 1 month ago

This is what python-oracledb imports: https://github.com/oracle/python-oracledb/blob/v2.4.1/src/oracledb/impl/thin/crypto.pyx#L32-L39 :

try:
    from cryptography import x509
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
    from cryptography.hazmat.primitives.asymmetric import padding
    from cryptography.hazmat.primitives.kdf import pbkdf2
except ImportError:
    HAS_CRYPTOGRAPHY = False

At connection time, the HAS_CRYPTOGRAPHY flag is checked and the DPY-3016 is thrown. Arguably we could change DPY-3016 to say "not appropriately installed".

Can you try packaging a test file that does the above imports and see if that gives you a better error?

zdenop commented 1 month ago

Thank you very much for these information! After some test&try I find out using x509 and pbkdf2 as hidden import (or importing them directly in my test.py) solves the problem.

So final cmd is like this: python -OO -m PyInstaller -F -c --noupx --noconfirm --hidden-import secrets --hidden-import asyncio --hidden-import uuid --hidden-import cryptography.hazmat.primitives.kdf.pbkdf2 --hidden-import cryptography.x509 test.py

cjbj commented 1 month ago

Thanks for debugging and sharing - and for using python-oracledb.

I'll close this issue.