Skip to main content

ChemQL --- Chemistry Query Language

Query chemistry like a database. Mix chemistry queries, Python, and shell commands in one interactive environment.

ChemQL is a command-line chemistry query language for exploring chemical elements, molecules, and reactions. Version 1.2.4 combines database-style chemistry queries, reaction tools, Python interoperability, reusable functions and macros, and a persistent shell in one scriptable environment. It combines a small SQL-inspired query syntax with a persistent Python environment, reaction utilities, optional external molecule lookup, and tools for running repeatable scripts.

Version covered by this README: 1.2.4
The examples below describe the ChemQL 1.2.4 source. Dataset contents and external-service availability can affect individual lookup results.

Contents

Highlights

  • Three queryable chemistry sources: elements, molecules, and reactions.
  • Database-style filtering: equality, inequality, numeric comparisons, pattern matching, containment, and grouped Boolean logic.
  • Useful result operations: choose the first or last match, sort ascending or descending, limit results, count matches, and project selected fields.
  • Readable results: one selected field returns a list; multiple fields are formatted as a column-aligned table.
  • Quick lookups: find elements by name or symbol, molecules by name or formula, and reactions by name, identifier, or equation.
  • External molecule lookup: ChemQL can try local data first and then use online chemistry services, including PubChem and the NIST Chemistry WebBook, when available.
  • Reaction exploration: search reaction records and match reactants against the current reaction conditions and catalysts.
  • Equation balancing: balance reaction equations with smallest positive integer coefficients.
  • Reaction conditions: configure temperature, pressure, and catalysts before running reaction matching.
  • Hybrid Python: execute Python expressions and statements, retain variables between commands, and embed ChemQL query results directly inside Python.
  • Preprocessor definitions: define reusable literal values with define and @NAME references.
  • User-defined functions: define reusable Python-backed functions with positional arguments and return values.
  • Source-generating macros: define reusable ChemQL command sequences and expand them with arguments.
  • Python control flow: use if/elif/else, for, while, break, and continue blocks.
  • Multiline Python: use [[[ ... ]]] for a single multiline Python block.
  • Integrated shell: execute commands in a persistent Bash or Windows Command Prompt session using backticks or fenced terminal blocks.
  • Comments and convenient command composition: use // comments, /// multiline comments, semicolon-separated commands, and backslash line continuation.
  • Interactive assistance: syntax highlighting, command completion, built-in help, and a browser-based periodic-table viewer.
  • Scriptable CLI: run a command, run a file, pipe input through standard input, disable ANSI escape sequences, or save clean output to a file.
  • Execution-history exports: save all, successful, or failed queries and results.
  • Python integration: import the query API and build queries programmatically.
  • Upgrade helper: request the latest release or a particular version from the CLI.

Installation

Install the Python package from PyPI:

pip install chemql-python

Upgrading the package or switching versions

If your chemql-python version is >=1.0.1, you can simply run

chemql --upgrade

Or to switch versions to for example 0.2.2

chemql --upgrade 0.2.2

However if you do not have chemql-python version >=1.0.1

pip install --upgrade chemql-python

Or to switch versions to for example 0.2.2

pip install --force-reinstall chemql-python==0.2.2

If your chemql-python version is >=1.1.0, and the terminal respond with something like "This environment is externally managed" then you can run

chemql --upgrade --force

OR

chemql --upgrade --dangerously

Else

pip install --upgrade chemql-python --break-system-packages

However, this is highly discouraged and creating a venv using python -m venv . and activating it with source .venv/bin/activate on MacOS/Linux or .\.venv\Scripts\Activate.ps1

Starting ChemQL

Start the interactive prompt:

chemql

At the prompt, type help or ? to see the built-in command reference. Type exit or press Ctrl+C to leave.

Check the installed version:

chemql --version

You can also use the language as a one-off command:

chemql -c 'search elements name = "Hydrogen"'

Your first queries

ChemQL has three main sources. Specify the source in a query:

search elements
search molecules
search reactions

A source can be selected for subsequent searches:

source elements
search name = "Hydrogen"
search number = 1

You can always state a source explicitly:

search elements name = "Hydrogen"
search molecules formula = "H2O"
search reactions reaction_type = "combustion"

To list the available fields for the active source---or the fields across all sources when no source is selected---use:

list all

Sources and data fields

ChemQL ships with local JSON datasets for its chemistry sources. Exact records and fields depend on the bundled dataset version.

Elements

The element records include fields such as:

name, symbol, number, atomic_mass, appearance, category, phase, density, melt, boil, molar_heat, period, group, block, shells, electron_configuration, electron_configuration_semantic, electron_affinity, electronegativity_pauling, ionization_energies, discovered_by, named_by, summary, source, image, bohr_model_image, bohr_model_3d, spectral_img, xpos, ypos, wxpos, wypos, and cpk-hex.

Example:

search elements symbol = "Fe" return name symbol number atomic_mass
search elements phase = "Gas" return name symbol
search elements electronegativity_pauling > 3 return name symbol electronegativity_pauling

The element number field is the atomic number.

Molecules

Molecule records include:

name, formula, elements, molecular_weight, iupac_name, smiles, cid, melting_point, boiling_point, density, state, bonds, and total_bond_energy.

Example:

search molecules formula = "H2O"
search molecules molecular_weight < 50 return name formula molecular_weight
search molecules state = "Liquid" return name formula

Bond information and calculated total bond energy are available when present in the bundled bond datasets.

Reactions

Reaction records include:

id, name, equation, reaction_type, reversible, reactants, products, conditions, notes, and source.

Example:

search reactions reaction_type = "combustion"
search reactions reversible = true return name equation
search reactions name like "*Haber*" return name equation source

Filtering and query logic

ChemQL supports the following comparison and matching operators:


Operator Meaning Example


= Equal search elements symbol = "O"

!= Not equal search elements phase != "Gas"

> Greater than search molecules molecular_weight > 100

< Less than search elements number < 10

>= Greater than or equal search elements number >= 90

<= Less than or equal search molecules molecular_weight <= 20

like Case-insensitive search molecules name like "*water*" wildcard pattern

like! Case-sensitive wildcard search elements name like! "Hydrogen" pattern

likep Pattern matching with search molecules formula likep "*H*" the parser's pattern
mode

has Check whether a value search molecules elements has "O" contains an item

Use and and or to combine conditions:

search elements number > 10 and number < 20
search molecules name like "*acid*" or name like "*base*"

Parentheses let you group conditions:

search molecules (name like "*water*" or formula = "H2O") and molecular_weight < 25

Patterns are useful when you only know part of a name or formula. For exact supported pattern behavior, try a query against the local dataset and inspect the results.

Sorting, limiting, counting, and returning fields

These operations can be added to a search query.

Sort

search elements sort number
search molecules sort molecular_weight desc
search reactions sort name asc

Use asc for ascending or desc for descending order.

Limit

search molecules limit 10
search elements number > 20 sort number limit 5

Count

search molecules count
search reactions reversible = true count

First and last

search elements first number > 10
search elements last number < 20

You can also put first or last immediately after search:

search first elements number > 10
search last molecules molecular_weight < 100

Return only selected fields

A single field returns a one-dimensional list. Multiple fields return a table.

search molecules molecular_weight < 20 return name
search molecules molecular_weight < 20 return name formula molecular_weight
search reactions reversible = true return name equation source

Filtering and result operations can be combined:

search elements number > 10 and number < 30 sort number desc limit 5 return name symbol number

Set operations

Query results can be combined using union or intersection:

search elements number < 10 union search elements number > 90
search molecules name like "*water*" intersection search molecules molecular_weight < 50

These operations are useful when you want to combine or compare result sets.

Quick lookup commands

Find an element

findel "He"
findel "Hydrogen"

findel searches element names and symbols.

Find a molecule

findmol "H2O"
findmol "Water"
findmol "Caffeine" return name formula molecular_weight

findmol checks the local molecule dataset first, then can try external lookup if no local match is found.

Find a reaction

findre "Haber process"
findre "RHEA:10000"
findre "H2 + N2"
findre "Haber process" return name equation source

findre searches reaction names, identifiers, and equations.

View the periodic table

view

This opens ChemQL's bundled periodic-table page in your default browser.

Molecules from external chemistry sources

When a molecule is not found locally, ChemQL can attempt an online lookup using external chemistry services such as PubChem and the NIST Chemistry WebBook.

findmol "acetone"
findmol "caffeine"
findmol "water"

The lookup code can retrieve or derive properties including molecular identifiers and basic chemical data; availability depends on the external service, network access, and whether a matching record exists. External lookup is not required for ordinary searches against the bundled local dataset.

Chemical reactions

ChemQL can search stored reaction records and has commands for setting reaction conditions before attempting to match reactants.

Set temperature

Temperature values support Celsius (C), Fahrenheit (F), and Kelvin (K):

set temperature 450K
set temperature 150C
set temperature 300F
set temperature standard
set temperature room

standard corresponds to 0 °C; room corresponds to 25 °C.

Set pressure

Pressure values support Pa, N/m², Nm⁻², bar, and atm, as well as the standard and room presets:

set pressure 101325Pa
set pressure 2bar
set pressure 1atm
set pressure standard
set pressure room

The presets use 100000 Pa for standard and 101325 Pa for room.

Configure catalysts

set catalysts iron zinc
add catalyst "Vanadium oxide"
remove catalyst "Vanadium oxide"
set catalysts

set catalysts with no values clears the catalyst list. add catalyst adds a catalyst if it is not already present; remove catalyst removes a matching catalyst.

Inspect current conditions

conditions

Unset temperature or pressure values are shown as not set.

Match reactants

react N2 3H2

react attempts to find a matching reaction using the supplied reactants and the current reaction conditions. The implementation uses a temperature tolerance of 5 K and a pressure tolerance of 5% for reaction matching. A match depends on the available reaction records and their conditions.

Balancing equations

Use balance to balance a chemical equation:

balance H2 + O2 -> H2O
balance Fe + O2 -> Fe2O3
balance N2 + H2 <-> NH3
  • -> represents an irreversible reaction.
  • <-> represents a reversible reaction.
  • ChemQL aims to return the smallest positive integer coefficients.

The result is represented as a reaction object, which can also be queried or inspected from Python.

Preprocessor, functions, and macros

ChemQL 1.2.5 adds three ways to reuse values and logic. These declarations are processed in source order: definitions affect later lines, not earlier ones. They persist during the current ChemQL process/session; they are not saved automatically between separate launches.

Literal definitions

Use define NAME value to store a literal replacement. Reference it as @NAME in later ChemQL commands, Python blocks, or shell commands.

define MAX 9
define ELEMENT "Hydrogen"
definitions

search elements number <= @MAX return name symbol number
search elements name = @ELEMENT
remove definition MAX

Definitions are textual replacements, not typed variables. They are expanded literally, including inside quoted strings, and a definition's replacement text is not recursively expanded in the same pass. definitions shows active definitions; remove definition NAME removes one.

User-defined functions

Declare a function with func NAME and finish it with endfunc. Use \1, \2, and so on as positional argument placeholders. A return line gives the function's result; arguments are evaluated as Python expressions.

func square
return [\1 * \1]
endfunc

square{5}
search molecules molecular_weight < square{5} return name formula molecular_weight

Functions can contain multiple commands and [[[ multiline Python blocks. Function-local Python assignments are restored after the call; return a value explicitly when you need one. Function calls use braces, for example name{argument1, argument2}.

Macros

Macros expand into ChemQL source lines. Declare one using define NAME{} and close it with enddefine. Use \1, \2, etc. for arguments, then call the macro with @NAME{arguments}.

define light_molecules{}
search molecules molecular_weight < \1 return name formula molecular_weight
enddefine

@light_molecules{50}

Macros are useful for reusable query recipes or command sequences. Arguments are substituted into the macro's source text, so quote or validate values appropriately when passing text that contains spaces or special characters.

Mixing ChemQL with Python

ChemQL is a hybrid language: a single-line Python expression or statement can be enclosed in square brackets.

[x = 10]
[print(x)]
[x * 2]

Python variables persist for the session, so later blocks can use values created earlier.

[import math]
[radius = 5]
[area = math.pi * radius**2]
[print(area)]

Python's built-in namespace is available, and math is preloaded. Only run Python or shell code you trust: these blocks execute real code, not a sandboxed query language.

Embed ChemQL queries in Python

Use {{ ... }} to run a ChemQL query and insert its result into Python code:

[hydrogen = {{ search elements name = "Hydrogen" }}]
[print(hydrogen)]

A query block can also be used on its own as a value-producing expression:

{{ search molecules molecular_weight < 20 return name formula }}

This is useful when you want ChemQL to find data and Python to calculate, transform, or display something using that data.

Python control-flow blocks

ChemQL supports block-style Python control flow:

[if value > 10]
    [print("Large")]
[elif value == 10]
    [print("Exactly ten")]
[else]
    [print("Small")]
[endblock]

Loop example:

[for element in {{ search elements number < 5 }}]
    [print(element.name, element.symbol)]
[endblock]

A while block is also supported:

[i = 0]
[while i < 3]
    [print(i)]
    [i += 1]
[endblock]

Use [break] and [continue] inside loops. As with ordinary Python, make sure a while loop has a condition that eventually becomes false unless you intentionally want it to continue.

Multiline Python blocks

For longer Python code, use [[[ to start a block and a line containing ]]] to finish it:

[[[
values = {{ search elements number < 10 return name }}
for value in values:
    print(value)
]]]

ChemQL executes the block as one Python unit and captures its printed output as one result. Keep the closing ]]] on its own line.

Running shell commands

ChemQL can run shell commands using backticks. It keeps a shell session alive so commands can share shell state.

`echo Hello from the shell`
`pwd`

For a multiline command, use a fenced block. The opening fence can optionally name a shell:

```bash
echo "First line"
echo "Second line"
```

Windows users can use a cmd fence:

```cmd
echo Hello from Windows
ver
```

Supported opening forms include a plain triple-backtick fence and fences labelled bash, sh, cmd, or terminal. Close the block with a line containing three backticks.

Security note: shell blocks run real operating-system commands with your user's permissions. Review commands before executing them, especially commands copied from untrusted sources.

Comments, semicolons, and line continuation

Single-line comments

Use // for comments:

search elements number < 10 // The first nine elements

The comment marker is intended to be recognized outside quoted strings.

Multiline comments

Use /// to begin and end a multiline comment:

/// This is a comment.
It can continue across multiple lines.
The whole comment is ignored. ///
search elements symbol = "O"

A multiline comment can also be written with opening and closing markers on the same line.

Semicolon-separated commands

Run multiple ChemQL commands on one line with semicolons:

source elements; search name = "Hydrogen"; search number = 8

ChemQL's command splitter tracks quotes and bracketed/query expressions so semicolons inside quoted strings or protected blocks are not treated as command separators.

Line continuation

End a line with \ to continue the command on the next line:

search elements \
number > 10 and \
number < 20 \
sort number desc \
limit 5

The continued lines are treated as one command.

Scripts, pipes, and output files

Run a command

chemql -c 'search elements symbol = "O"'

Run a file

Save commands in a .cql or .chemql file, for example explore.cql:

search elements number < 10 return name symbol number
search molecules molecular_weight < 50 sort molecular_weight return name formula molecular_weight

Run it:

chemql -f explore.cql

Both .cql and .chemql are suitable file extensions; the CLI accepts a file path.

Pipe commands through standard input

echo 'search elements symbol = "O"' | chemql

You can also pipe a multi-line script into ChemQL:

cat explore.cql | chemql

On Windows PowerShell, use Get-Content explore.cql | chemql or redirect a file into the command.

Show version and upgrade

chemql --version
chemql --upgrade
chemql --upgrade 1.2.4

--upgrade installs the latest published chemql-python release; supplying a version requests that specific release. The optional --force (also accepted as --dangerously) bypasses system-package protections. Use that option only when you understand the consequences for your Python environment.

Disable ANSI escape sequences

chemql --no-ansi -c 'search elements symbol = "O"'

This is useful when redirecting output to logs or processing it with other tools.

Write clean output to a file

Use -o / --output together with -c or -f:

chemql -c 'search elements number < 10 return name symbol' -o elements.txt
chemql -f explore.cql --output results.txt

The output file is written without ANSI escape sequences. -o requires either -c or -f.

Session history and exports

ChemQL records queries and results processed during the session. Use dump to export that history to a UTF-8 text file.

dump session.txt
dump all session.txt
dump good session-successes.txt
dump bad session-errors.txt
dump all queries queries.txt
dump good results successful-results.txt
dump bad results failed-results.txt

Available forms:

Command What it exports


dump FILE All recorded queries and results dump all FILE All recorded queries and results dump good FILE Successful executions dump bad FILE Failed executions dump all queries FILE All recorded queries only dump good queries FILE Successful queries only dump bad queries FILE Failed queries only dump all results FILE All results only dump good results FILE Results from successful executions dump bad results FILE Results from failed executions

The good and bad categories use ChemQL's execution-status tracking. Shell command exit codes are not necessarily equivalent to ChemQL's own error tracking.

Terminal experience

In interactive mode, ChemQL provides:

  • Syntax highlighting for ChemQL commands, operators, fields, strings, and related syntax.
  • Tab completion for commands, sources, fields, and context-aware suggestions.
  • Built-in help through help or ?.
  • A periodic-table viewer through view.
  • ANSI styling for readable terminal output, with --no-ansi available for plain output.
  • Persistent Python variables across Python blocks.
  • A persistent shell session for backtick and fenced shell commands.
  • Friendly exit controls: type exit or press Ctrl+C.

Python API

ChemQL can also be used from Python. The public query function is execute_query_text():

from chemql import execute_query_text

result = execute_query_text('search elements name = "Hydrogen"')
print(result)

execute_query_text() accepts a query string and returns its query result. Depending on the query, that result may be a chemistry object, list, table-like result, count, string, or None.

The higher-level execute_query() wrapper is also available:

from chemql import execute_query

result = execute_query('search molecules formula = "H2O"')
print(result)

The package exposes chemistry classes such as Element, Molecule, and Reaction, as well as helper functions including search, union, and intersection. Public APIs can evolve between versions; consult the installed source and help() for the exact version you use.

Query syntax reference

A typical query follows this pattern:

search [first|last|all] SOURCE [conditions] [sort FIELD [asc|desc]] [limit N] [count] [return FIELD ...]

Examples:

search elements number = 8
search molecules name like "*acid*" sort molecular_weight limit 10
search reactions reversible = true return name equation

Common commands:

Command Purpose


search ... Query a source source NAME Set the current source list all List fields findel VALUE Find an element findmol VALUE Find a molecule findre VALUE Find a reaction react ... Match reactants to stored reactions balance ... Balance a chemical equation set temperature VALUE Set reaction temperature set pressure VALUE Set reaction pressure set catalysts ... Replace the catalyst list add catalyst NAME Add a catalyst remove catalyst NAME Remove a catalyst conditions Show reaction conditions view Open the periodic-table viewer dump ... Export execution history clear Clear the terminal help / ? Show help version Print the ChemQL version exit Leave the interactive prompt

Examples

Find noble gases

search elements category like "*noble gas*" return name symbol number

Find relatively light molecules

search molecules molecular_weight < 50 sort molecular_weight asc limit 10 return name formula molecular_weight

Find reactions of a particular type

search reactions reaction_type = "combustion" return name equation reversible

Explore and export a session

search elements number < 20 return name symbol number
search molecules molecular_weight < 100 return name formula molecular_weight
dump all results chemistry-results.txt

Combine a query with Python

[light_molecules = {{ search molecules molecular_weight < 50 return name }}]
[print("Found names:", light_molecules)]

Use ChemQL from a Python script

from chemql import execute_query_text

elements = execute_query_text(
    'search elements number < 10 return name symbol'
)
print(elements)

Troubleshooting

  • No source selected: specify a source in the query, such as search elements ..., or set one with source elements.
  • Unknown field: run list all after selecting a source to see its available field names. Use number for an element's atomic number in the current data model.
  • No local molecule match: findmol may try online lookup, which requires network access and an available external service.
  • Output contains terminal escape codes: add --no-ansi or use -o FILE with -c or -f.
  • A multiline block is incomplete: close a Python block with ]]] on its own line or a terminal block with three backticks on its own line.
  • Python or shell command behaves unexpectedly: remember that these execute real code in your environment. Check quotes, indentation, and the exact command before running it.
  • A reaction does not match: check the available reaction records, the reactant spelling and stoichiometry, and the temperature, pressure, and catalyst settings.

Safety and scope

ChemQL is a chemistry data/query tool, not a replacement for authoritative chemical references, laboratory procedures, or professional safety guidance. Dataset coverage and online service responses may be incomplete. Validate important scientific results against appropriate primary or authoritative sources.

Python and shell blocks execute real code with your operating-system user's permissions. Do not run scripts or commands you do not trust.


ChemQL --- Python Chemistry Query Language

Metadata

Release files for chemql-python 1.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chemql-python 1.2.5
File Size Uploaded Provenance
chemql_python-1.2.5.tar.gz 248.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for chemql-python 1.2.5
File Interpreter ABI Platform
chemql_python-1.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 494.4 kB

Release files / chemql_python-1.2.5.tar.gz

Download URL chemql_python-1.2.5.tar.gz
Size 248.1 kB
Tags Source
SHA-256 checksum
How to use checksums
11d8a0cf7a507d8c7d838f263b90e3724a5c7c7f75379f2980dd0d4a6c628143
BLAKE2b-256 checksum
How to use checksums
adeca8ea2e5027fcdee372b9d913005bbca4cc76e9de0fd1fb79e3fb6358ae54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / chemql_python-1.2.5-py3-none-any.whl

Download URL chemql_python-1.2.5-py3-none-any.whl
Size 246.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0aececf7013d9591d20892a75a8866475774ac4e0a98b46c42961341c4ddf28
BLAKE2b-256 checksum
How to use checksums
91764524e4cb87cd56a2380dd62e450489803e53b2aae9886fbb10be7e9b6132
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Security for chemql-python 1.2.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.2.5 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page