🧪 CDK Python Wrapper
A simple and reliable Python wrapper for calculating CDK (Chemistry Development Kit) molecular descriptors and fingerprints. This library takes care of installing a matching Java runtime, dispatching molecules to the bundled CDKdesc executable, and collecting the results into a tidy pandas DataFrame — so you can stay in RDKit/pandas-land.
✨ Features
- 🧬 288 descriptors & 14 fingerprint types — 223 1D/2D and 65 3D descriptors, plus FP, ExtFP, EStateFP, GraphFP, MACCSFP, PubchemFP, SubFP, KRFP, AP2DFP, HybridFP, LingoFP, SPFP, SigFP and CircFP fingerprints, straight from CDK.
- ☕ Zero Java setup — automatically downloads, caches and reuses a matching JRE on first use; nothing to install by hand.
- ⚡ Parallel by design — spread the work across multiple CPU cores with configurable
njobs/chunksize, each worker running its own single-core-pinned JVM. - 🧯 Never silently misaligned — molecules that fail, get skipped, or lack hydrogens/conformers are handled explicitly and reported, never dropped without a trace.
- 📊 pandas-native output — results come back as a ready-to-use
DataFrame, one row per molecule. - 🧾 Optional CDK canonical SMILES — get back the SMILES CDK itself parsed alongside the descriptor/fingerprint values.
- 🔀 SD or SMILES interchange format — choose whether molecules are handed to CDK as V2000 SD blocks or as plain SMILES.
- 🔍 Rich metadata — inspect every descriptor's name, description, type and dimensionality (1D/2D/3D) programmatically via
get_details().
✍️ Copyright and Citation Notice
Olivier J. M. Béquignon is neither the copyright holder of CDK nor responsible for it. The work carried out here concerns:
- the Python wrapper,
- the CDKdesc executable.
Citing
If you use this wrapper in your research, please cite the original CDK publications in addition to this software package:
-
Original CDK papers:
Willighagen, E.L. et al. (2017), The Chemistry Development Kit (CDK) v2.0: atom typing, depiction, molecular formulas, and substructure searching. Journal of Cheminformatics, 9, 33. DOI: 10.1186/s13321-017-0220-4
May, J.W. and Steinbeck, C. (2014), Efficient ring perception for the Chemistry Development Kit. Journal of Cheminformatics, 6, 3. DOI: 10.1186/1758-2946-6-3
Steinbeck, C. et al. (2006), Recent Developments of the Chemistry Development Kit (CDK) - An Open-Source Java Library for Chemo- and Bioinformatics. Current Pharmaceutical Design, 12(17), 2111-2120. DOI: 10.2174/138161206777585274
Steinbeck, C. et al. (2003), The Chemistry Development Kit (CDK): An Open-Source Java Library for Chemo- and Bioinformatics. Journal of Chemical Information and Computer Sciences, 43(2), 493-500. DOI: 10.1021/ci025584y
-
This wrapper:
Béquignon, O. J. M. CDK_pywrapper: a Python wrapper for CDK molecular descriptors and fingerprints. https://github.com/OlivierBeq/CDK_pywrapper
📦 Installation
pip install CDK-pywrapper
Or from source:
git clone https://github.com/OlivierBeq/CDK_pywrapper.git
pip install ./CDK_pywrapper
🛠️ Requirements
- Python 3.11+
- RDKit
💡 Usage
1D and 2D descriptors
from CDK_pywrapper import CDK
from rdkit import Chem
smiles_list = [
# erlotinib
"n1cnc(c2cc(c(cc12)OCCOC)OCCOC)Nc1cc(ccc1)C#C",
# midecamycin
"CCC(=O)O[C@@H]1CC(=O)O[C@@H](C/C=C/C=C/[C@@H]([C@@H](C[C@@H]([C@@H]([C@H]1OC)O[C@H]2[C@@H]([C@H]([C@@H]([C@H](O2)C)O[C@H]3C[C@@]([C@H]([C@@H](O3)C)OC(=O)CC)(C)O)N(C)C)O)CC=O)C)O)C",
# selenofolate
"C1=CC(=CC=C1C(=O)NC(CCC(=O)OCC[Se]C#N)C(=O)O)NCC2=CN=C3C(=N2)C(=O)NC(=N3)N",
# cisplatin
"N.N.Cl[Pt]Cl",
]
mols = [Chem.AddHs(Chem.MolFromSmiles(smiles)) for smiles in smiles_list]
cdk = CDK()
print(cdk.calculate(mols))
This calculates 223 molecular descriptors (23 1D and 200 2D).
Optionally, request the canonical SMILES CDK itself generated for each parsed molecule:
print(cdk.calculate(mols, cdk_smiles=True))
3D descriptors
By default, the ignore_3D parameter is set to True, preventing any 3D descriptor from being calculated.
Should molecules with 3D coordinates be provided, one can turn on the additional 65 three-dimensional descriptors:
from rdkit.Chem import AllChem
for mol in mols:
_ = AllChem.EmbedMolecule(mol)
cdk3d = CDK(ignore_3D=False)
print(cdk3d.calculate(mols))
⚠️ A warning is raised if molecules lack hydrogens. ⚠️ An exception is raised if a 3D descriptor is requested for a conformer-less molecule.
mol = Chem.MolFromSmiles('CCC')
cdk3d = CDK(ignore_3D=False)
print(cdk3d.calculate([mol]))
# ValueError: Cannot calculate the 3D descriptors of a conformer-less molecule
Fingerprints
from CDK_pywrapper import CDK, FPType
cdk = CDK(fingerprint=FPType.PubchemFP)
print(cdk.calculate(mols))
Fingerprint size and search depth can be tuned for the fingerprints that support it:
cdk = CDK(fingerprint=FPType.FP, nbits=2048, depth=8)
print(cdk.calculate(mols))
The following fingerprints can be calculated:
| FPType | Fingerprint name |
|---|---|
| FP | CDK fingerprint |
| ExtFP | Extended CDK fingerprint (includes 25 bits for ring features and isotopic masses) |
| EStateFP | Electrotopological state fingerprint (79 bits) |
| GraphFP | CDK fingerprinter ignoring bond orders |
| MACCSFP | Public MACCS fingerprint |
| PubchemFP | PubChem substructure fingerprint |
| SubFP | Fingerprint describing 307 substructures |
| KRFP | Klekota-Roth fingerprint |
| AP2DFP | Atom pair 2D fingerprint as implemented in PaDEL |
| HybridFP | CDK fingerprint ignoring aromaticity |
| LingoFP | LINGO fingerprint |
| SPFP | Fingerprint based on the shortest paths between two atoms |
| SigFP | Signature fingerprint |
| CircFP | Circular fingerprint |
⚡ Parallel processing
Speed things up by spreading molecules across several CPU cores. Each worker runs its own single-core-pinned JVM, so parallelism comes purely from the number of processes spawned — not from oversubscribing the host:
cdk = CDK()
print(cdk.calculate(mols, njobs=8))
By default, molecules are auto-balanced evenly across njobs workers (chunksize=None), which minimizes JVM startup overhead while keeping every worker busy — the fastest setting for most workloads. A fixed chunksize can be provided instead if finer control is needed.
🔍 Details about descriptors
Details about all descriptors and fingerprints — name, description, type and dimensionality — can be obtained as a DataFrame:
print(CDK.get_details())
Or for a single descriptor by name:
print(CDK.get_details('MW'))
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
📚 API Documentation
class CDK(ignore_3D=True, fingerprint=None, nbits=1024, depth=6, backend_smiles=False):
Constructor of a CDK calculator for molecular descriptors or a fingerprint.
Parameters
- ignore_3D : bool
Whether to exclude the 65 3D molecular descriptors (default:
True). Ignored iffingerprintis set. - fingerprint : FPType | None
Type of fingerprint to calculate (default:
None). IfNone, descriptors are calculated instead. - nbits : int Number of bits in the fingerprint, for fingerprints with a configurable size (default: 1024).
- depth : int Search depth of the fingerprint, for fingerprints with a configurable depth (default: 6).
- backend_smiles : bool
Use SMILES rather than the V2000 SD format as the interchange format with the CDKdesc backend
(default:
False). Ignored ifignore_3D=False.
def calculate(mols, show_banner=True, cdk_smiles=False, njobs=1, chunksize=None):
Calculates CDK molecular descriptors and/or a fingerprint. Installs a matching JRE on first use if none is found.
Parameters
- mols : Iterable[Chem.Mol] RDKit molecule objects for which to obtain CDK descriptors/fingerprints (must have 3D conformers if 3D descriptors are requested).
- show_banner : bool Displays default notice about CDK.
- cdk_smiles : bool
If
True, also return the canonical SMILES CDK generated for each parsed molecule. - njobs : int
Number of concurrent processes used to calculate descriptors/fingerprints in parallel; must
not exceed the number of available CPU cores. Each spawned Java process is pinned to a single
core (
-XX:ActiveProcessorCount=1), since parallelism comes from spawningnjobsOS processes rather than from letting each JVM oversubscribe the host's full core count. - chunksize : int | None
Number of molecules processed per worker process. If
None(default), molecules are auto-balanced across allnjobsworkers so every worker gets work. Ignored ifnjobsis 1. - return_type : pd.DataFrame Pandas DataFrame containing CDK molecular descriptors and/or fingerprint values, one row per molecule.
@staticmethod
def get_details(desc_name=None):
Obtain metadata about either one or all descriptors/fingerprint bits.
Parameters
- desc_name : str | None
Name of the descriptor to obtain details about (default:
None). IfNone, returns details about all 288 descriptors. - return_type : pd.DataFrame
Pandas DataFrame with columns
Name,Description,TypeandDimensions.
Metadata
Release files for CDK-pywrapper 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cdk_pywrapper-1.0.0.tar.gz | 43.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cdk_pywrapper-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.4 MB
Release files / cdk_pywrapper-1.0.0.tar.gz
| Download URL | cdk_pywrapper-1.0.0.tar.gz |
|---|---|
| Size | 43.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62b1a8d94474d1da402fc3c4dff860e280314aef5c35656b84c7e8931bc2d1f7
|
|
BLAKE2b-256 checksum How to use checksums |
563130768a59220dcbae78aef12808647a332cba6d926f8841948a082956e666
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|
Release files / cdk_pywrapper-1.0.0-py3-none-any.whl
| Download URL | cdk_pywrapper-1.0.0-py3-none-any.whl |
|---|---|
| Size | 43.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cf529decb916c02c105e0a602c5e84e48ae08a23564c351f00f4a585152fa80d
|
|
BLAKE2b-256 checksum How to use checksums |
4692a941fdd0a93ad8968b2f6efa649012ce00b76a8d50203e956ea06be20021
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|