Skip to main content

MolHarbour

image Ruff codecov

MolHarbour is a unofficial Python wrapper for the Molport REST API. It allows you to search for chemical compounds and retrieve information about them. Additionally, MolHarbour unifies the Molport API variables names and verifies the response data using wonderful Pydantic models.

This library is not affiliated with Molport in any way. Molport is a registered trademark of Molport SIA.

The project was initiated as a part of my master's thesis and and is based on refactored scripts which I wrote to retrive commercial availablity of compounds in chembl database.

Installation

From PyPI

pip install molharbor

From source

pip install git+https://github.com/asiomchen/molharbor

Quickstart

Authentication

To start using MolHarbour, you need to create an instance of the Molport class and log in to the Molport API using your username and password or API key.

from molharbor import Molport

molport = Molport()
molport.login(username="john.spade", password="fasdga34a3")

or API key

molport.login(api_key="16072de6-d318-4324-a82c-08c7dfe64d5d")

Compound search

You can search for compounds using the search method. All the search types are supported( via SearchType enum). Additionally, you can specify the maximum number of results to return using the max_results parameter, and the minimum similarity threshold using the similarity parameter (it is used only for similarity search).

Exact search

from molharbor import SearchType

molport.find("O=C(O)c1ccccc1", search_type=SearchType.EXACT)

[
    [
        MolportCompound(
            smiles="OC(=O)c1ccccc1",
            molport_id="Molport-000-871-563",
            link="https://www.molport.com/shop/compound/Molport-000-871-563",
        ),
        MolportCompound(
            smiles="[2H]c1c([2H])c([2H])c(c([2H])c1[2H])C(O)=O",
            molport_id="Molport-003-927-939",
            link="https://www.molport.com/shop/compound/Molport-003-927-939",
        ),
        MolportCompound(
            smiles="O[13C](=O)c1ccccc1",
            molport_id="Molport-003-929-055",
            link="https://www.molport.com/shop/compound/Molport-003-929-055",
        ),
        MolportCompound(
            smiles="OC(=O)[13c]1[13cH][13cH][13cH][13cH][13cH]1",
            molport_id="Molport-046-688-787",
            link="https://www.molport.com/shop/compound/Molport-046-688-787",
        ),
    ]
]

Similarity search

molport.find("O=C(O)c1ccccc1", search_type=SearchType.SIMILARITY, max_results=5)

[
    [
        MolportCompound(
            smiles="OC(=O)c1ccccc1",
            molport_id="Molport-000-871-563",
            link="https://www.molport.com/shop/compound/Molport-000-871-563",
        ),
        MolportCompound(
            smiles="[2H]c1c([2H])c([2H])c(c([2H])c1[2H])C(O)=O",
            molport_id="Molport-003-927-939",
            link="https://www.molport.com/shop/compound/Molport-003-927-939",
        ),
        MolportCompound(
            smiles="O[13C](=O)c1ccccc1",
            molport_id="Molport-003-929-055",
            link="https://www.molport.com/shop/compound/Molport-003-929-055",
        ),
        MolportCompound(
            smiles="[Zn++].[O-]C(=O)c1ccccc1.[O-]C(=O)c1ccccc1",
            molport_id="Molport-003-986-949",
            link="https://www.molport.com/shop/compound/Molport-003-986-949",
        ),
        MolportCompound(
            smiles="OC(=O)[13c]1[13cH][13cH][13cH][13cH][13cH]1",
            molport_id="Molport-046-688-787",
            link="https://www.molport.com/shop/compound/Molport-046-688-787",
        ),
    ]
]

Superstructure search

molport.find("O=C(O)c1ccccc1", search_type=SearchType.SUPERSTRUCTURE, max_results=5)

[
    [
        MolportCompound(
            smiles="CC=O",
            molport_id="Molport-001-783-184",
            link="https://www.molport.com/shop/compound/Molport-001-783-184",
        ),
        MolportCompound(
            smiles="OCc1ccccc1",
            molport_id="Molport-001-783-216",
            link="https://www.molport.com/shop/compound/Molport-001-783-216",
        ),
        MolportCompound(
            smiles="C=O",
            molport_id="Molport-001-785-627",
            link="https://www.molport.com/shop/compound/Molport-001-785-627",
        ),
        MolportCompound(
            smiles="CCO",
            molport_id="Molport-001-785-844",
            link="https://www.molport.com/shop/compound/Molport-001-785-844",
        ),
        MolportCompound(
            smiles="O",
            molport_id="Molport-003-926-090",
            link="https://www.molport.com/shop/compound/Molport-003-926-090",
        ),
    ]
]

Substructure search

molport.find("O=C(O)c1ccccc1", search_type=SearchType.SUBSTRUCTURE, max_results=5)

[
    [
        MolportCompound(
            smiles="OC(=O)c1ccc2[nH]c(S)nc2c1",
            molport_id="Molport-000-004-519",
            link="https://www.molport.com/shop/compound/Molport-000-004-519",
        ),
        MolportCompound(
            smiles="OC(=O)c1cc(C#N)c(Cl)cc1Cl",
            molport_id="Molport-051-434-827",
            link="https://www.molport.com/shop/compound/Molport-051-434-827",
        ),
        MolportCompound(
            smiles="OC(=O)c1ccc(cc1)-c1ccc(cc1)-c1ccc(cc1)N(c1ccc(cc1)-c1ccc(cc1)-c1ccc(cc1)C(O)=O)c1ccc(cc1)-c1ccc(cc1)-c1ccc(cc1)C(O)=O",
            molport_id="Molport-051-434-831",
            link="https://www.molport.com/shop/compound/Molport-051-434-831",
        ),
        MolportCompound(
            smiles="COC(=O)[C@]1(C[C@H](OC(C)=O)[C@@H](NC(C)=O)[C@@H](O1)[C@H](OC(C)=O)[C@@H](COC(C)=O)OC(C)=O)O[C@H]1[C@@H](OC(=O)c2ccccc2)[C@@H](COC(=O)c2ccccc2)O[C@@H](Oc2ccc(OC)cc2)[C@@H]1OC(=O)c1ccccc1",
            molport_id="Molport-051-434-926",
            link="https://www.molport.com/shop/compound/Molport-051-434-926",
        ),
        MolportCompound(
            smiles="[Na+].[Na+].OC(=O)CN(CC([O-])=O)Cc1cc2c(Oc3cc(O)c(CN(CC(O)=O)CC([O-])=O)cc3C22OC(=O)c3ccccc23)cc1O",
            molport_id="Molport-051-435-130",
            link="https://www.molport.com/shop/compound/Molport-051-435-130",
        ),
    ]
]

Raw response manipulation

MolHarbour design to simplify commonn tasks so .find() method returns a list of MolportCompound objects (which itself is a dataclass object with smiles, molport_id and link field).

However, you can access the raw response using the return_response parameter. Returned Response object inherits from Pydantic BaseModel and contains all the fields from the Molport API response with type validation provided by Pydantic. All the fields have the same name as in Molport API docs, only lowercase and the spaces are replaced with underscores( e.g. Shipment Type -> shipment_type)

from molharbor import SearchType

molport.find(
    "O=C(O)c1ccccc1",
    search_type=SearchType.SUBSTRUCTURE,
    max_results=1,
    return_response=False,
)

[
    [
        MolportCompound(
            smiles="OC(=O)c1cc(C#N)c(Cl)cc1Cl",
            molport_id="Molport-051-434-827",
            link="https://www.molport.com/shop/compound/Molport-051-434-827",
        )
    ]
]

vs

molport.find("O=C(O)c1ccccc1", 
              search_type=SearchType.SUBSTRUCTURE, 
              max_results=1, 
              return_response=True)

[Response(result=Result(status=1, message='Substructure search completed!'), data=Data(molecules=[Molecule(id=45........

Suppliers search

Having a Molport ID, you can search for suppliers using the get_suppliers method. Similar to the find() method, you can receive either a raw Pydantic response or a processed list of SupplierOffer models. Each offer represents one available packing from a supplier catalogue.

offers = molport.get_suppliers("Molport-001-794-639")

Or you could use id values of MolportCompound objects returned by find() method

result = molport.find("C[C@H](CS)C(=O)N1CCC[C@H]1C(O)=O", search_type=SearchType.EXACT, max_results=1)[0]
result

MolportCompound(smiles='C[C@H](CS)C(=O)N1CCC[C@H]1C(O)=O', molport_id='Molport-001-794-639', link=...

offers = molport.get_suppliers(result.molport_id)

Processed supplier offers

The returned models contain the supplier, catalogue, and packing fields from the MolPort response with Pydantic validation.

first_offer = offers[0]
first_offer.supplier_name
first_offer.price
first_offer.model_dump()

Applications that use pandas can construct a dataframe without making it a MolHarbor dependency:

import pandas as pd

df = pd.DataFrame(offer.model_dump() for offer in offers)

Raw response

molport.get_suppliers("Molport-000-871-563", return_response=True)

ResponseSupplier(result=Result(status=1, message='Molecule found!'), data=DataSupplier(molecule=Molecule2(id=871563, molport_id='Molport-000-871-563', smiles='OC(=O)c1ccccc1', .....

Contributing

Contributions are welcome!

We use uv for dependency management. To install the dependencies for development, run:

uv sync

Please make sure to update tests as appropriate. We use ruff for code formatting and linting. Please make sure to run it before opening a pull request.

Additionally, pre-commit hooks are set up to run ruff before each commit. To install them, run:

pre-commit install

Thank you for your contributions!

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

molharbor-0.1.6.tar.gz (82.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

molharbor-0.1.6-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file molharbor-0.1.6.tar.gz.

File metadata

  • Download URL: molharbor-0.1.6.tar.gz
  • Upload date:
  • Size: 82.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for molharbor-0.1.6.tar.gz
Algorithm Hash digest
SHA256 0f5aacf52f71f5a41239b24235aad8139d5859f8a9a1181ee51d5290f91efbc0
MD5 d9ac45eb0924282dca9025c3994d62a9
BLAKE2b-256 94d2af48160dec381b41f311492162eb91f07080ce2bbc05a3695c3ec74f0bb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for molharbor-0.1.6.tar.gz:

Publisher: release.yml on asiomchen/molharbor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file molharbor-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: molharbor-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for molharbor-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 1992cd122fab7a6d7f00dbde0998cf95e5f2c39233e1f36093f1b841412b9079
MD5 86007f3f98533062a7382ec2e6c8400c
BLAKE2b-256 74d272389147a9895ed16bb8d2dd090ce18100c9eaabf82724395e1db101b1a1

See more details on using hashes here.

Provenance

The following attestation bundles were made for molharbor-0.1.6-py3-none-any.whl:

Publisher: release.yml on asiomchen/molharbor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page