chemql-python 1.2.6__tar.gz → 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chemql_python-1.3.1/PKG-INFO +904 -0
- chemql_python-1.3.1/README.md +891 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/pyproject.toml +1 -1
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/__init__.py +1415 -370
- chemql_python-1.3.1/src/chemql_python.egg-info/PKG-INFO +904 -0
- chemql_python-1.2.6/PKG-INFO +0 -1067
- chemql_python-1.2.6/README.md +0 -1054
- chemql_python-1.2.6/src/chemql_python.egg-info/PKG-INFO +0 -1067
- {chemql_python-1.2.6 → chemql_python-1.3.1}/LICENSE +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/setup.cfg +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/__main__.py +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/BondEnergies.json +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/MoleculeBonds.json +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/Molecules.json +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/PeriodicTableJSON.json +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/Reactions.json +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql/html/periodic_table.html +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql_python.egg-info/SOURCES.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql_python.egg-info/dependency_links.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql_python.egg-info/entry_points.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql_python.egg-info/requires.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/src/chemql_python.egg-info/top_level.txt +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/tests/test_external_molecule_lookup.py +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/tests/test_public_api.py +0 -0
- {chemql_python-1.2.6 → chemql_python-1.3.1}/tests/test_reactions.py +0 -0
|
@@ -0,0 +1,904 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chemql-python
|
|
3
|
+
Version: 1.3.1
|
|
4
|
+
Summary: A chemistry-focused query language and REPL
|
|
5
|
+
Author-email: Mohammad Rakibul Islam <rakibulofficial1017@gmail.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: prompt_toolkit>=3.0
|
|
10
|
+
Provides-Extra: test
|
|
11
|
+
Requires-Dist: pytest>=8.0; extra == "test"
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# ChemQL
|
|
15
|
+
|
|
16
|
+
**ChemQL** is a Python-powered chemistry query language and interactive
|
|
17
|
+
command-line environment. Query chemical datasets with a compact,
|
|
18
|
+
SQL-inspired syntax, inspect elements and molecules, look up reactions,
|
|
19
|
+
balance equations, and combine chemistry queries with Python and shell
|
|
20
|
+
commands.
|
|
21
|
+
|
|
22
|
+
- **Version:** `1.3.1`
|
|
23
|
+
- **PyPI distribution:** `chemql-python`
|
|
24
|
+
- **Python import / CLI name:** `chemql`
|
|
25
|
+
- **Author:** Mohammad Rakibul Islam
|
|
26
|
+
|
|
27
|
+
> ChemQL is a learning and productivity tool, not a substitute for
|
|
28
|
+
> authoritative chemical references or professional laboratory guidance.
|
|
29
|
+
> Results depend on the available data and implemented calculations.
|
|
30
|
+
|
|
31
|
+
## Contents
|
|
32
|
+
|
|
33
|
+
- [Highlights](#highlights)
|
|
34
|
+
- [Installation](#installation)
|
|
35
|
+
- [Start and quick start](#start-and-quick-start)
|
|
36
|
+
- [Query language](#query-language)
|
|
37
|
+
- [Filters and result operations](#filters-and-result-operations)
|
|
38
|
+
- [Lookup commands](#lookup-commands)
|
|
39
|
+
- [Reaction tools](#reaction-tools)
|
|
40
|
+
- [Python integration](#python-integration)
|
|
41
|
+
- [Functions, definitions, and
|
|
42
|
+
macros](#functions-definitions-and-macros)
|
|
43
|
+
- [Structs and records](#structs-and-records)
|
|
44
|
+
- [Shell integration and scripting](#shell-integration-and-scripting)
|
|
45
|
+
- [CLI options and history export](#cli-options-and-history-export)
|
|
46
|
+
- [Python API](#python-api)
|
|
47
|
+
- [Data sources and network access](#data-sources-and-network-access)
|
|
48
|
+
- [Troubleshooting](#troubleshooting)
|
|
49
|
+
- [Security](#security)
|
|
50
|
+
- [Development and contributing](#development-and-contributing)
|
|
51
|
+
- [License and attribution](#license-and-attribution)
|
|
52
|
+
|
|
53
|
+
## Highlights
|
|
54
|
+
|
|
55
|
+
- Search bundled element, molecule, and reaction datasets.
|
|
56
|
+
- Filter records using comparisons, wildcard matching, boolean logic,
|
|
57
|
+
and collection membership.
|
|
58
|
+
- Sort, limit, count, and project query results.
|
|
59
|
+
- Combine compatible result sets with `union` and `intersection`.
|
|
60
|
+
- Find elements, molecules, and reactions with convenience commands.
|
|
61
|
+
- Balance supported chemical equations and match supplied reactants
|
|
62
|
+
against stored reactions.
|
|
63
|
+
- Set reaction temperature, pressure, and catalysts for supported
|
|
64
|
+
matching.
|
|
65
|
+
- Use Python statements, expressions, variables, control flow,
|
|
66
|
+
functions, macros, and structured values.
|
|
67
|
+
- Execute shell commands and multiline shell blocks from the REPL.
|
|
68
|
+
- Export recorded commands and results.
|
|
69
|
+
- Use the command-line interface or import ChemQL from Python.
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
ChemQL is distributed as `chemql-python`; the executable and import name
|
|
74
|
+
are `chemql`.
|
|
75
|
+
|
|
76
|
+
**Requirements:** Python 3.10 or newer. `prompt_toolkit` is installed as
|
|
77
|
+
a dependency. Internet access is needed only for optional online lookups
|
|
78
|
+
or package upgrades.
|
|
79
|
+
|
|
80
|
+
Install from PyPI:
|
|
81
|
+
|
|
82
|
+
``` bash
|
|
83
|
+
python -m pip install --upgrade chemql-python
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Windows PowerShell
|
|
87
|
+
|
|
88
|
+
``` powershell
|
|
89
|
+
py -m venv .venv
|
|
90
|
+
.\.venv\Scripts\Activate.ps1
|
|
91
|
+
python -m pip install --upgrade chemql-python
|
|
92
|
+
chemql
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Linux, macOS, or WSL
|
|
96
|
+
|
|
97
|
+
``` bash
|
|
98
|
+
python3 -m venv .venv
|
|
99
|
+
source .venv/bin/activate
|
|
100
|
+
python -m pip install --upgrade chemql-python
|
|
101
|
+
chemql
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
If `chemql` is not found, confirm that you installed the package into
|
|
105
|
+
the Python environment you are currently using:
|
|
106
|
+
|
|
107
|
+
``` bash
|
|
108
|
+
python -m pip show chemql-python
|
|
109
|
+
python -m pip install --upgrade chemql-python
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Start and quick start
|
|
113
|
+
|
|
114
|
+
Start the interactive prompt:
|
|
115
|
+
|
|
116
|
+
``` bash
|
|
117
|
+
chemql
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
At the prompt, try:
|
|
121
|
+
|
|
122
|
+
``` text
|
|
123
|
+
help
|
|
124
|
+
version
|
|
125
|
+
list all
|
|
126
|
+
findel "He"
|
|
127
|
+
findmol "Water"
|
|
128
|
+
findre "Haber process"
|
|
129
|
+
search elements symbol = "Fe"
|
|
130
|
+
search molecules molecular_weight < 50 sort molecular_weight limit 10
|
|
131
|
+
balance H2 + O2 -> H2O
|
|
132
|
+
exit
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- `help` or `?` prints the built-in guide.
|
|
136
|
+
- `version` prints the running version.
|
|
137
|
+
- `list all` shows available sources and fields.
|
|
138
|
+
- `exit` leaves the prompt.
|
|
139
|
+
|
|
140
|
+
## Query language
|
|
141
|
+
|
|
142
|
+
A typical query starts with `search`, a source, optional conditions, and
|
|
143
|
+
optional result operations:
|
|
144
|
+
|
|
145
|
+
``` text
|
|
146
|
+
search <source> <conditions> <result operations>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Available sources:
|
|
150
|
+
|
|
151
|
+
Source Contents
|
|
152
|
+
------------- -----------------------------------------
|
|
153
|
+
`elements` Element / periodic-table records
|
|
154
|
+
`molecules` Bundled molecule records and properties
|
|
155
|
+
`reactions` Bundled reaction records
|
|
156
|
+
|
|
157
|
+
Use `source` to set the current source for commands that rely on it:
|
|
158
|
+
|
|
159
|
+
``` text
|
|
160
|
+
source elements
|
|
161
|
+
source molecules
|
|
162
|
+
source reactions
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Select fields
|
|
166
|
+
|
|
167
|
+
Use `return` to choose which fields are displayed:
|
|
168
|
+
|
|
169
|
+
``` text
|
|
170
|
+
search elements symbol = "O" return name symbol number atomic_mass
|
|
171
|
+
search molecules name like "*water*" return name formula molecular_weight
|
|
172
|
+
search reactions reversible = true return name equation source
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
A single returned field can be displayed as a list; multiple fields are
|
|
176
|
+
formatted as a table. Use `list all` to check valid field names.
|
|
177
|
+
|
|
178
|
+
## Filters and result operations
|
|
179
|
+
|
|
180
|
+
### Comparison operators
|
|
181
|
+
|
|
182
|
+
Operator Meaning
|
|
183
|
+
------------- ------------------------------
|
|
184
|
+
`=` / `!=` Equal / not equal
|
|
185
|
+
`>` / `<` Greater / less than
|
|
186
|
+
`>=` / `<=` Greater / less than or equal
|
|
187
|
+
|
|
188
|
+
``` text
|
|
189
|
+
search elements number >= 10
|
|
190
|
+
search molecules molecular_weight < 25
|
|
191
|
+
search reactions reversible = true
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Matching and logic
|
|
195
|
+
|
|
196
|
+
Operator Meaning
|
|
197
|
+
------------- ----------------------------------------
|
|
198
|
+
`like` Case-insensitive pattern matching
|
|
199
|
+
`like!` Case-sensitive pattern matching
|
|
200
|
+
`likep` Pattern-oriented matching
|
|
201
|
+
`has` Tests whether a value contains an item
|
|
202
|
+
`and`, `or` Combine conditions
|
|
203
|
+
`( ... )` Group conditions
|
|
204
|
+
|
|
205
|
+
The `*` wildcard matches a sequence of characters in `like` patterns:
|
|
206
|
+
|
|
207
|
+
``` text
|
|
208
|
+
search molecules name like "*water*"
|
|
209
|
+
search elements number > 10 and number < 20
|
|
210
|
+
search molecules (name like "*water*" or formula = "H2O") and molecular_weight < 25
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Result operations
|
|
214
|
+
|
|
215
|
+
-------------------------------------------------------------------------
|
|
216
|
+
Operation Purpose Example
|
|
217
|
+
----------------------- ----------------------- -------------------------
|
|
218
|
+
`return FIELD ...` Choose fields to `return name formula`
|
|
219
|
+
display
|
|
220
|
+
|
|
221
|
+
`sort FIELD` Sort results `sort molecular_weight`
|
|
222
|
+
|
|
223
|
+
`sort FIELD asc` Ascending order `sort number asc`
|
|
224
|
+
|
|
225
|
+
`sort FIELD desc` Descending order `sort number desc`
|
|
226
|
+
|
|
227
|
+
`limit N` Limit result count `limit 10`
|
|
228
|
+
|
|
229
|
+
`first` / `last` Select an end result `first`
|
|
230
|
+
|
|
231
|
+
`count` Count matches `count`
|
|
232
|
+
|
|
233
|
+
`union` Combine result sets See below
|
|
234
|
+
|
|
235
|
+
`intersection` Keep common results See below
|
|
236
|
+
-------------------------------------------------------------------------
|
|
237
|
+
|
|
238
|
+
Examples:
|
|
239
|
+
|
|
240
|
+
``` text
|
|
241
|
+
search molecules molecular_weight < 20 sort molecular_weight asc limit 5
|
|
242
|
+
search elements number < 10 union search elements number > 90
|
|
243
|
+
search molecules name like "*water*" intersection search molecules molecular_weight < 50
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Set operations are intended for compatible result sets.
|
|
247
|
+
|
|
248
|
+
## Lookup commands
|
|
249
|
+
|
|
250
|
+
### `findel`
|
|
251
|
+
|
|
252
|
+
Find an element by name or symbol:
|
|
253
|
+
|
|
254
|
+
``` text
|
|
255
|
+
findel "He"
|
|
256
|
+
findel "Helium"
|
|
257
|
+
findel "Fe"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### `findmol`
|
|
261
|
+
|
|
262
|
+
Find a molecule by name or formula. ChemQL searches locally first and
|
|
263
|
+
may try external lookup services if the local dataset has no match.
|
|
264
|
+
|
|
265
|
+
``` text
|
|
266
|
+
findmol "Water"
|
|
267
|
+
findmol "H2O"
|
|
268
|
+
findmol "Ethanol"
|
|
269
|
+
findmol "Water" return name formula molecular_weight
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
External molecule lookup requires network access and can fail if a
|
|
273
|
+
service is unavailable.
|
|
274
|
+
|
|
275
|
+
### `findre`
|
|
276
|
+
|
|
277
|
+
Find a reaction by name, ID, or equation:
|
|
278
|
+
|
|
279
|
+
``` text
|
|
280
|
+
findre "Haber process"
|
|
281
|
+
findre "ethanol"
|
|
282
|
+
findre "RHEA:..."
|
|
283
|
+
findre "propanol" return name equation source reactants products
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
`findre` checks local reaction records first and can then try external
|
|
287
|
+
sources such as Chempirical and Rhea. External results may have
|
|
288
|
+
different metadata from local records. For deterministic offline
|
|
289
|
+
searching, use `search reactions ...`, which searches the bundled
|
|
290
|
+
dataset only.
|
|
291
|
+
|
|
292
|
+
## Reaction tools
|
|
293
|
+
|
|
294
|
+
### Balance equations
|
|
295
|
+
|
|
296
|
+
``` text
|
|
297
|
+
balance H2 + O2 -> H2O
|
|
298
|
+
balance Fe + O2 -> Fe2O3
|
|
299
|
+
balance N2 + H2 <-> NH3
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
The balancer supports the formula notation accepted by its parser.
|
|
303
|
+
Complex ionic equations or unusual formula syntax may require checking
|
|
304
|
+
or simplifying. `->` denotes a forward equation; reversible arrows such
|
|
305
|
+
as `<->` are accepted by supported command syntax.
|
|
306
|
+
|
|
307
|
+
### Match reactants to stored reactions
|
|
308
|
+
|
|
309
|
+
``` text
|
|
310
|
+
react N2 3H2
|
|
311
|
+
react H2 O2
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`react` attempts to match the supplied reactants against stored reaction
|
|
315
|
+
records and the active conditions. It is a dataset lookup, not a
|
|
316
|
+
general-purpose reaction predictor, and cannot guarantee that a reaction
|
|
317
|
+
will occur.
|
|
318
|
+
|
|
319
|
+
### Conditions
|
|
320
|
+
|
|
321
|
+
``` text
|
|
322
|
+
set temperature 723K
|
|
323
|
+
set temperature 150C
|
|
324
|
+
set temperature 300F
|
|
325
|
+
set temperature room
|
|
326
|
+
set temperature standard
|
|
327
|
+
|
|
328
|
+
set pressure 101325Pa
|
|
329
|
+
set pressure 2bar
|
|
330
|
+
set pressure 1atm
|
|
331
|
+
set pressure room
|
|
332
|
+
set pressure standard
|
|
333
|
+
|
|
334
|
+
set catalysts iron zinc
|
|
335
|
+
add catalyst "Vanadium oxide"
|
|
336
|
+
remove catalyst "Vanadium oxide"
|
|
337
|
+
set catalysts
|
|
338
|
+
conditions
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Supported temperature units include `C`, `F`, and `K`. Pressure syntax
|
|
342
|
+
includes `Pa`, `N/m^2`, `Nm^-2`, `bar`, and `atm` forms accepted by the
|
|
343
|
+
parser. The built-in help describes `standard` as 0 °C and 100000 Pa,
|
|
344
|
+
and `room` as 25 °C and 101325 Pa. Use `set catalysts` without names to
|
|
345
|
+
clear the catalyst list.
|
|
346
|
+
|
|
347
|
+
Reaction matching and calculations depend on the bundled records and
|
|
348
|
+
implementation; they are not experimental validation or safety advice.
|
|
349
|
+
|
|
350
|
+
## Python integration
|
|
351
|
+
|
|
352
|
+
Square brackets execute Python statements or expressions, and Python
|
|
353
|
+
state can be reused in the session:
|
|
354
|
+
|
|
355
|
+
``` text
|
|
356
|
+
[x = 10]
|
|
357
|
+
[print(x)]
|
|
358
|
+
[x * 2]
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Use `{{ ... }}` to evaluate a ChemQL query as a Python value:
|
|
362
|
+
|
|
363
|
+
``` text
|
|
364
|
+
{{ search elements name = "Hydrogen" }}
|
|
365
|
+
let hydrogen = {{ search elements name = "Hydrogen" }}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The returned value depends on the query result shape.
|
|
369
|
+
|
|
370
|
+
## Control Flow
|
|
371
|
+
|
|
372
|
+
ChemQL supports conditional statements and loops, allowing you to control the execution of your code. Native control-flow syntax uses keywords such as `if`, `endif`, `while`, `endwhile`, `for`, and `endfor` without requiring square brackets.
|
|
373
|
+
|
|
374
|
+
### Conditional statements: `if`, `else`, and `endif`
|
|
375
|
+
|
|
376
|
+
Use `if` to execute a block only when a condition is true. The optional `else` block executes when the condition is false. Close the conditional with `endif`.
|
|
377
|
+
|
|
378
|
+
```text
|
|
379
|
+
let temperature = 25
|
|
380
|
+
|
|
381
|
+
if temperature > 30
|
|
382
|
+
print("It is hot")
|
|
383
|
+
else
|
|
384
|
+
print("It is not too hot")
|
|
385
|
+
endif
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
You can also use `if` without an `else`:
|
|
389
|
+
|
|
390
|
+
```text
|
|
391
|
+
if temperature > 20
|
|
392
|
+
print("Above 20 degrees")
|
|
393
|
+
endif
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### While loops: `while` and `endwhile`
|
|
397
|
+
|
|
398
|
+
A `while` loop repeats its body as long as its condition remains true. Use `endwhile` to close the loop.
|
|
399
|
+
|
|
400
|
+
```text
|
|
401
|
+
let counter = 0
|
|
402
|
+
|
|
403
|
+
while counter < 5
|
|
404
|
+
print(counter)
|
|
405
|
+
counter = counter + 1
|
|
406
|
+
endwhile
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Make sure the condition eventually becomes false; otherwise, the loop may run indefinitely.
|
|
410
|
+
|
|
411
|
+
### For loops: `for` and `endfor`
|
|
412
|
+
|
|
413
|
+
Use `for` to iterate over a sequence or other supported iterable. The loop ends at `endfor`.
|
|
414
|
+
|
|
415
|
+
```text
|
|
416
|
+
for i in range(5)
|
|
417
|
+
print(i)
|
|
418
|
+
endfor
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
This prints the numbers from `0` through `4`.
|
|
422
|
+
|
|
423
|
+
You can also iterate over a list:
|
|
424
|
+
|
|
425
|
+
```text
|
|
426
|
+
let fruits = ["Apple", "Banana", "Orange"]
|
|
427
|
+
|
|
428
|
+
for fruit in fruits
|
|
429
|
+
print(fruit)
|
|
430
|
+
endfor
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Nested control-flow blocks
|
|
434
|
+
|
|
435
|
+
Control-flow statements can be nested. Each closing keyword must match its corresponding opening statement.
|
|
436
|
+
|
|
437
|
+
```text
|
|
438
|
+
for i in range(3)
|
|
439
|
+
if i > 0
|
|
440
|
+
print(i)
|
|
441
|
+
endif
|
|
442
|
+
endfor
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
For nested loops, close the innermost loop first:
|
|
446
|
+
|
|
447
|
+
```text
|
|
448
|
+
for i in range(3)
|
|
449
|
+
for j in range(2)
|
|
450
|
+
print(i, j)
|
|
451
|
+
endfor
|
|
452
|
+
endfor
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Bracketed Python-style syntax
|
|
456
|
+
|
|
457
|
+
ChemQL also supports bracketed Python-style control-flow blocks, which use `endblock` as the closing keyword.
|
|
458
|
+
|
|
459
|
+
**Conditional example:**
|
|
460
|
+
|
|
461
|
+
```text
|
|
462
|
+
[if 3 > 2]
|
|
463
|
+
[print("True")]
|
|
464
|
+
[else]
|
|
465
|
+
[print("False")]
|
|
466
|
+
[endblock]
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**While loop example:**
|
|
470
|
+
|
|
471
|
+
```text
|
|
472
|
+
let counter = 0
|
|
473
|
+
|
|
474
|
+
[while counter < 3]
|
|
475
|
+
[print(counter)]
|
|
476
|
+
[counter = counter + 1]
|
|
477
|
+
[endblock]
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**For loop example:**
|
|
481
|
+
|
|
482
|
+
```text
|
|
483
|
+
[for i in range(5)]
|
|
484
|
+
[print(i)]
|
|
485
|
+
[endblock]
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Summary
|
|
489
|
+
|
|
490
|
+
| Native syntax | Purpose |
|
|
491
|
+
|---|---|
|
|
492
|
+
| `if ... endif` | Conditional execution |
|
|
493
|
+
| `if ... else ... endif` | Choose between two branches |
|
|
494
|
+
| `while ... endwhile` | Repeat while a condition is true |
|
|
495
|
+
| `for ... endfor` | Iterate over a sequence |
|
|
496
|
+
| `endblock` | Close a bracketed Python-style control-flow block |
|
|
497
|
+
|
|
498
|
+
Use native control-flow syntax for ChemQL's keyword-based blocks, and bracketed syntax when writing Python-style blocks. Always match each opening statement with the appropriate closing keyword.
|
|
499
|
+
|
|
500
|
+
For a multiline Python block, start with `[[[` and close with `]]]` on
|
|
501
|
+
its own line:
|
|
502
|
+
|
|
503
|
+
``` text
|
|
504
|
+
[[[
|
|
505
|
+
for i in range(3):
|
|
506
|
+
print(i)
|
|
507
|
+
]]]
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
Use `let` to assign session values:
|
|
511
|
+
|
|
512
|
+
``` text
|
|
513
|
+
let answer = 42
|
|
514
|
+
let double = answer * 2
|
|
515
|
+
```
|
|
516
|
+
## Error Handling and Cleanup
|
|
517
|
+
|
|
518
|
+
ChemQL provides `risk`, `fix`, `cleanup`, and `signal` for handling errors, responding to failures, and organizing cleanup logic.
|
|
519
|
+
|
|
520
|
+
### `risk`
|
|
521
|
+
|
|
522
|
+
Use `risk` to mark a block of code that may encounter an error and needs special handling.
|
|
523
|
+
|
|
524
|
+
```text
|
|
525
|
+
risk
|
|
526
|
+
[result = 10 / 0]
|
|
527
|
+
endrisk
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
This illustrates the idea of protecting potentially failing code. The exact behaviour depends on ChemQL's implementation of `risk`.
|
|
531
|
+
|
|
532
|
+
### `fix`
|
|
533
|
+
|
|
534
|
+
Use `fix` to define how ChemQL should respond when an error occurs in a corresponding `risk` block.
|
|
535
|
+
|
|
536
|
+
```text
|
|
537
|
+
risk
|
|
538
|
+
[result = 10 / 0]
|
|
539
|
+
fix
|
|
540
|
+
[print("An error occurred")]
|
|
541
|
+
endrisk
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
This example illustrates the intended relationship between `risk` and `fix`. Check the implementation for the precise syntax and whether execution continues after an error.
|
|
545
|
+
|
|
546
|
+
### `cleanup`
|
|
547
|
+
|
|
548
|
+
Use `cleanup` to organize code that should run as part of a cleanup phase associated with a protected operation.
|
|
549
|
+
|
|
550
|
+
```text
|
|
551
|
+
risk
|
|
552
|
+
[print("Performing operation")]
|
|
553
|
+
fix
|
|
554
|
+
[print("Handling an error")]
|
|
555
|
+
cleanup
|
|
556
|
+
[print("Cleaning up")]
|
|
557
|
+
endrisk
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Cleanup logic is useful for keeping resource-management steps separate from the main operation and its error-handling logic.
|
|
561
|
+
|
|
562
|
+
### `signal`
|
|
563
|
+
|
|
564
|
+
Use `signal` to explicitly raise or report an error when a condition cannot be handled normally.
|
|
565
|
+
|
|
566
|
+
```text
|
|
567
|
+
if temperature < 0
|
|
568
|
+
signal "Temperature cannot be negative"
|
|
569
|
+
endif
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
A signal can make an invalid state or failed operation explicit instead of allowing execution to proceed silently.
|
|
573
|
+
|
|
574
|
+
### Summary
|
|
575
|
+
|
|
576
|
+
| Keyword | Purpose |
|
|
577
|
+
|---|---|
|
|
578
|
+
| `risk` | Marks potentially failing code for special handling |
|
|
579
|
+
| `fix` | Specifies error-handling behaviour |
|
|
580
|
+
| `cleanup` | Organizes cleanup logic |
|
|
581
|
+
| `signal` | Raises or reports an error |
|
|
582
|
+
| `endrisk` | Ends the risk handler |
|
|
583
|
+
|
|
584
|
+
These features help make ChemQL scripts easier to maintain by separating normal execution, error handling, and cleanup responsibilities.
|
|
585
|
+
|
|
586
|
+
## Functions, definitions, and macros
|
|
587
|
+
|
|
588
|
+
These definitions are session-local and should be declared before they
|
|
589
|
+
are used.
|
|
590
|
+
|
|
591
|
+
### Literal definitions
|
|
592
|
+
|
|
593
|
+
``` text
|
|
594
|
+
define MAX 9
|
|
595
|
+
search elements number <= @MAX
|
|
596
|
+
definitions
|
|
597
|
+
remove definition MAX
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
A definition is a literal replacement, not a Python variable. Choose
|
|
601
|
+
names and replacement text carefully.
|
|
602
|
+
|
|
603
|
+
### Functions
|
|
604
|
+
|
|
605
|
+
Functions use `func`, positional placeholders such as `\1` and `\2`, and
|
|
606
|
+
`endfunc`:
|
|
607
|
+
|
|
608
|
+
``` text
|
|
609
|
+
func square
|
|
610
|
+
return [\1 * \1]
|
|
611
|
+
endfunc
|
|
612
|
+
|
|
613
|
+
square{5}
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
Example with two arguments:
|
|
617
|
+
|
|
618
|
+
``` text
|
|
619
|
+
func add
|
|
620
|
+
return [\1 + \2]
|
|
621
|
+
endfunc
|
|
622
|
+
|
|
623
|
+
add{10, 32}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
Test more complex function bodies against your installed build before
|
|
627
|
+
using them in larger scripts.
|
|
628
|
+
|
|
629
|
+
### Macros
|
|
630
|
+
|
|
631
|
+
Macros expand reusable ChemQL text with positional placeholders:
|
|
632
|
+
|
|
633
|
+
``` text
|
|
634
|
+
define light{}
|
|
635
|
+
search molecules molecular_weight < \1 return name formula
|
|
636
|
+
enddefine
|
|
637
|
+
|
|
638
|
+
@light{50}
|
|
639
|
+
macros
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
Use `\1`, `\2`, and subsequent placeholders for arguments. The `macros`
|
|
643
|
+
command lists definitions in the current session.
|
|
644
|
+
|
|
645
|
+
## Structs and records
|
|
646
|
+
|
|
647
|
+
ChemQL v1.3.0 includes named structured values, constructors, variables,
|
|
648
|
+
and user-defined methods. This area is evolving; test advanced method
|
|
649
|
+
dispatch and operator overloading in the exact build you use.
|
|
650
|
+
|
|
651
|
+
``` text
|
|
652
|
+
struct Fruit
|
|
653
|
+
name
|
|
654
|
+
price
|
|
655
|
+
endstruct
|
|
656
|
+
|
|
657
|
+
let apple = Fruit{name="Apple", price=35}
|
|
658
|
+
apple
|
|
659
|
+
apple.name
|
|
660
|
+
apple.price
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
The implementation also supports defining methods on structured types.
|
|
664
|
+
Special methods such as `__add__` are intended for custom behaviour, but
|
|
665
|
+
do not assume every Python data-model feature or operator dispatch path
|
|
666
|
+
is fully implemented.
|
|
667
|
+
|
|
668
|
+
## Shell integration and scripting
|
|
669
|
+
|
|
670
|
+
Backticks execute a command through the host system shell:
|
|
671
|
+
|
|
672
|
+
``` text
|
|
673
|
+
`pwd`
|
|
674
|
+
`python --version`
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
The shell and command syntax depend on the operating system: Windows
|
|
678
|
+
PowerShell / Command Prompt differ from Bash and other POSIX shells.
|
|
679
|
+
|
|
680
|
+
Multiline shell blocks use triple backticks. Labels such as `bash`,
|
|
681
|
+
`sh`, `cmd`, and `terminal` are recognised, but the commands must be
|
|
682
|
+
valid for the host shell:
|
|
683
|
+
|
|
684
|
+
```` text
|
|
685
|
+
```bash
|
|
686
|
+
echo "Starting"
|
|
687
|
+
python --version
|
|
688
|
+
echo "Finished"
|
|
689
|
+
```
|
|
690
|
+
````
|
|
691
|
+
|
|
692
|
+
Other conveniences:
|
|
693
|
+
|
|
694
|
+
``` text
|
|
695
|
+
// A single-line comment
|
|
696
|
+
///
|
|
697
|
+
A multiline comment.
|
|
698
|
+
///
|
|
699
|
+
view
|
|
700
|
+
clear
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Commands can be separated with semicolons, and a trailing backslash can
|
|
704
|
+
continue a line where supported by the input processor. `view` opens the
|
|
705
|
+
bundled periodic-table viewer in a browser where the environment allows
|
|
706
|
+
it. `clear` clears the terminal.
|
|
707
|
+
|
|
708
|
+
## CLI options and history export
|
|
709
|
+
|
|
710
|
+
Command Purpose
|
|
711
|
+
------------------------------- -----------------------------------------------
|
|
712
|
+
`chemql` Start the REPL
|
|
713
|
+
`chemql --version` Print the version
|
|
714
|
+
`chemql -c "COMMAND"` Execute a command
|
|
715
|
+
`chemql -f FILE` Execute commands from a file
|
|
716
|
+
`chemql --no-ansi` Disable ANSI styling
|
|
717
|
+
`chemql -c "COMMAND" -o FILE` Write command output to a text file
|
|
718
|
+
`chemql --upgrade` Upgrade to the latest release
|
|
719
|
+
`chemql --upgrade VERSION` Request a particular release
|
|
720
|
+
`chemql --force` Force upgrade past system-package protections
|
|
721
|
+
|
|
722
|
+
Examples:
|
|
723
|
+
|
|
724
|
+
``` bash
|
|
725
|
+
chemql --version
|
|
726
|
+
chemql -c 'search elements symbol = "O"'
|
|
727
|
+
chemql -c 'search molecules name like "*water*" return name formula' -o results.txt
|
|
728
|
+
chemql -f examples.chemql
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
Quote commands according to your shell's rules.
|
|
732
|
+
|
|
733
|
+
The `dump` command exports recorded execution history, queries, and
|
|
734
|
+
results:
|
|
735
|
+
|
|
736
|
+
``` text
|
|
737
|
+
dump history.txt
|
|
738
|
+
dump all queries queries.txt
|
|
739
|
+
dump good results results.txt
|
|
740
|
+
dump bad executions failures.txt
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Supported forms include `dump all|good|bad FILE`,
|
|
744
|
+
`dump all|good|bad queries FILE`, and `dump all|good|bad results FILE`.
|
|
745
|
+
`good` and `bad` select successful and failed executions respectively.
|
|
746
|
+
|
|
747
|
+
## Python API
|
|
748
|
+
|
|
749
|
+
``` python
|
|
750
|
+
from chemql import execute_query_text, execute_query
|
|
751
|
+
|
|
752
|
+
result = execute_query_text('search elements symbol = "O"')
|
|
753
|
+
print(result)
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
`execute_query_text()` accepts a query string and returns its formatted
|
|
757
|
+
execution result. `execute_query()` is a lower-level entry point;
|
|
758
|
+
accepted inputs and return values depend on the query path.
|
|
759
|
+
|
|
760
|
+
The package also exposes helpers including `search`, `union`,
|
|
761
|
+
`intersection`, `find_molecule`, `find_reaction`, `search_reactions`,
|
|
762
|
+
and `balance_stoichiometry`. For example:
|
|
763
|
+
|
|
764
|
+
``` python
|
|
765
|
+
from chemql import find_molecule, find_reaction
|
|
766
|
+
|
|
767
|
+
water = find_molecule("Water")
|
|
768
|
+
reaction = find_reaction("Haber process", external=False)
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
`find_reaction(value, external=False)` restricts reaction lookup to the
|
|
772
|
+
local dataset; its default lookup can use online fallback sources. Check
|
|
773
|
+
the installed module for the precise public API of your release.
|
|
774
|
+
|
|
775
|
+
## Data sources and network access
|
|
776
|
+
|
|
777
|
+
### Bundled data
|
|
778
|
+
|
|
779
|
+
Bundled local data is the primary source for normal queries and keeps
|
|
780
|
+
core searching available offline. The package uses files for element /
|
|
781
|
+
periodic-table records, molecule records and properties, reaction
|
|
782
|
+
records and conditions, molecule bonds, and bond-energy data. Coverage
|
|
783
|
+
depends on the data shipped with the release.
|
|
784
|
+
|
|
785
|
+
### External molecule services
|
|
786
|
+
|
|
787
|
+
If a molecule is not found locally, `findmol` can attempt an external
|
|
788
|
+
lookup. The code includes PubChem integration and additional lookup
|
|
789
|
+
paths. External requests require network access and may fail because of
|
|
790
|
+
timeouts, outages, rate limits, changed API responses, or missing
|
|
791
|
+
credentials for a particular provider.
|
|
792
|
+
|
|
793
|
+
### External reaction services
|
|
794
|
+
|
|
795
|
+
If `findre` cannot find a local reaction, it can try Chempirical and
|
|
796
|
+
Rhea. These services are fallback sources, not replacements for
|
|
797
|
+
`Reactions.json`. In contrast, `search reactions ...` and
|
|
798
|
+
`search_reactions()` search local records only.
|
|
799
|
+
|
|
800
|
+
Remote records may differ from local records in fields, participant
|
|
801
|
+
formats, equations, and annotations. Some operations may not be possible
|
|
802
|
+
if a remote source does not provide all the required structured
|
|
803
|
+
information. A failed lookup does not prove that a substance or reaction
|
|
804
|
+
does not exist.
|
|
805
|
+
|
|
806
|
+
Preserve source attribution and check upstream dataset licences and
|
|
807
|
+
reuse terms when redistributing data.
|
|
808
|
+
|
|
809
|
+
## Troubleshooting
|
|
810
|
+
|
|
811
|
+
### `chemql` is not recognised
|
|
812
|
+
|
|
813
|
+
Check that the package was installed in the active environment:
|
|
814
|
+
|
|
815
|
+
``` bash
|
|
816
|
+
python -m pip show chemql-python
|
|
817
|
+
python -m pip install --upgrade chemql-python
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
### No matches are returned
|
|
821
|
+
|
|
822
|
+
- Use `list all` to verify source and field names.
|
|
823
|
+
- Start with a simple query and add conditions one at a time.
|
|
824
|
+
- Remember that `search reactions` is local-only; use `findre` if you
|
|
825
|
+
want its external fallback.
|
|
826
|
+
- Check spelling, formula notation, and wildcard patterns.
|
|
827
|
+
|
|
828
|
+
### Online lookup fails
|
|
829
|
+
|
|
830
|
+
Check network access and retry later. Remote services may be temporarily
|
|
831
|
+
unavailable. Use local data when you need predictable offline behaviour.
|
|
832
|
+
|
|
833
|
+
### A reaction lacks fields you expected
|
|
834
|
+
|
|
835
|
+
Inspect `source`, `id`, `equation`, `reactants`, and `products`. Local
|
|
836
|
+
and external records can have different metadata and participant
|
|
837
|
+
coverage.
|
|
838
|
+
|
|
839
|
+
### Python block syntax errors
|
|
840
|
+
|
|
841
|
+
Check Python indentation, close `[if]`, `[for]`, and `[while]` blocks
|
|
842
|
+
with `[endblock]`, and close `[[[` blocks with `]]]` on a line by
|
|
843
|
+
itself. Reduce the block to a small reproducible example if necessary.
|
|
844
|
+
|
|
845
|
+
### Shell commands behave differently
|
|
846
|
+
|
|
847
|
+
ChemQL invokes the host shell. PowerShell, Command Prompt, Bash, and
|
|
848
|
+
other shells have different syntax and quoting rules. Test a failing
|
|
849
|
+
command in your normal terminal to isolate shell-specific behaviour.
|
|
850
|
+
|
|
851
|
+
### ANSI escape codes appear in output
|
|
852
|
+
|
|
853
|
+
Try `chemql --no-ansi`, or use `-o FILE` to write command output to a
|
|
854
|
+
plain-text file where supported.
|
|
855
|
+
|
|
856
|
+
## Security
|
|
857
|
+
|
|
858
|
+
ChemQL's Python blocks and shell commands execute real code with the
|
|
859
|
+
permissions of the running process; they are not a sandbox.
|
|
860
|
+
|
|
861
|
+
- Run only scripts and commands you trust.
|
|
862
|
+
- Shell commands can read, modify, or delete files and launch
|
|
863
|
+
programs.
|
|
864
|
+
- Network lookup terms are sent to the relevant external service.
|
|
865
|
+
- Do not place passwords, tokens, or other secrets in scripts,
|
|
866
|
+
exported histories, or public bug reports.
|
|
867
|
+
- Verify important chemical calculations and claims against
|
|
868
|
+
authoritative references.
|
|
869
|
+
|
|
870
|
+
## Development and contributing
|
|
871
|
+
|
|
872
|
+
ChemQL is actively evolving. Areas for future improvement may include
|
|
873
|
+
broader parser and multiline tests, additional validation of struct
|
|
874
|
+
methods and operator overloading, more robust participant normalization
|
|
875
|
+
across remote databases, clearer handling of ambiguous online results,
|
|
876
|
+
improved data provenance, and wider compatibility testing across
|
|
877
|
+
Windows, Linux, macOS, and WSL. These are possible development
|
|
878
|
+
directions, not a promise that every item is already implemented.
|
|
879
|
+
|
|
880
|
+
Bug reports and contributions are welcome. When reporting a problem,
|
|
881
|
+
include:
|
|
882
|
+
|
|
883
|
+
1. ChemQL version (`chemql --version`).
|
|
884
|
+
2. Operating system and Python version.
|
|
885
|
+
3. A minimal reproducible query or script.
|
|
886
|
+
4. Actual output and expected output.
|
|
887
|
+
5. Whether the issue occurs with local data only or requires an
|
|
888
|
+
external lookup.
|
|
889
|
+
|
|
890
|
+
Do not include passwords, API tokens, or unrelated private information
|
|
891
|
+
in issue reports.
|
|
892
|
+
|
|
893
|
+
## License and attribution
|
|
894
|
+
|
|
895
|
+
[MIT License](https://github.com/rakibulofficial1017/ChemQL/blob/main/LICENSE)
|
|
896
|
+
|
|
897
|
+
Created by [Mohammad Rakibul Islam](https://github.com/rakibulofficial1017).
|
|
898
|
+
Source code: [rakibulofficial1017/ChemQL](https://github.com/rakibulofficial1017/ChemQL).
|
|
899
|
+
|
|
900
|
+
------------------------------------------------------------------------
|
|
901
|
+
|
|
902
|
+
For the command reference that matches your installed build, type `help`
|
|
903
|
+
inside ChemQL. Use `list all` to inspect fields available in your
|
|
904
|
+
bundled datasets.
|