chemql-python 1.0.3__tar.gz → 1.1.0__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.
Files changed (27) hide show
  1. chemql_python-1.1.0/PKG-INFO +985 -0
  2. chemql_python-1.1.0/README.md +972 -0
  3. {chemql_python-1.0.3 → chemql_python-1.1.0}/pyproject.toml +1 -1
  4. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/__init__.py +357 -135
  5. chemql_python-1.1.0/src/chemql_python.egg-info/PKG-INFO +985 -0
  6. chemql_python-1.0.3/PKG-INFO +0 -443
  7. chemql_python-1.0.3/README.md +0 -430
  8. chemql_python-1.0.3/src/chemql_python.egg-info/PKG-INFO +0 -443
  9. {chemql_python-1.0.3 → chemql_python-1.1.0}/LICENSE +0 -0
  10. {chemql_python-1.0.3 → chemql_python-1.1.0}/setup.cfg +0 -0
  11. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/__main__.py +0 -0
  12. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/BondEnergies.json +0 -0
  13. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/MoleculeBonds.json +0 -0
  14. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/Molecules.json +0 -0
  15. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/PeriodicTableJSON.json +0 -0
  16. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/Reactions.json +0 -0
  17. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
  18. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
  19. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql/html/periodic_table.html +0 -0
  20. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql_python.egg-info/SOURCES.txt +0 -0
  21. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql_python.egg-info/dependency_links.txt +0 -0
  22. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql_python.egg-info/entry_points.txt +0 -0
  23. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql_python.egg-info/requires.txt +0 -0
  24. {chemql_python-1.0.3 → chemql_python-1.1.0}/src/chemql_python.egg-info/top_level.txt +0 -0
  25. {chemql_python-1.0.3 → chemql_python-1.1.0}/tests/test_external_molecule_lookup.py +0 -0
  26. {chemql_python-1.0.3 → chemql_python-1.1.0}/tests/test_public_api.py +0 -0
  27. {chemql_python-1.0.3 → chemql_python-1.1.0}/tests/test_reactions.py +0 -0
@@ -0,0 +1,985 @@
1
+ Metadata-Version: 2.4
2
+ Name: chemql-python
3
+ Version: 1.1.0
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 --- Chemistry Query Language
15
+
16
+ **Query chemistry like a database. Mix chemistry queries, Python, and
17
+ shell commands in one interactive environment.**
18
+
19
+ ChemQL is a command-line chemistry query language for exploring chemical
20
+ elements, molecules, and reactions. It combines a small SQL-inspired
21
+ query syntax with a persistent Python environment, reaction utilities,
22
+ optional external molecule lookup, and tools for running repeatable
23
+ scripts.
24
+
25
+ > **Version covered by this README:** 1.1.0\
26
+ > The examples below describe the current ChemQL 1.1.0 source. Dataset
27
+ > contents and external-service availability can affect individual
28
+ > lookup results.
29
+
30
+ ## Contents
31
+
32
+ - [Highlights](#highlights)
33
+ - [Installation](#installation)
34
+ - [Starting ChemQL](#starting-chemql)
35
+ - [Your first queries](#your-first-queries)
36
+ - [Sources and data fields](#sources-and-data-fields)
37
+ - [Filtering and query logic](#filtering-and-query-logic)
38
+ - [Sorting, limiting, counting, and returning
39
+ fields](#sorting-limiting-counting-and-returning-fields)
40
+ - [Quick lookup commands](#quick-lookup-commands)
41
+ - [Molecules from external chemistry
42
+ sources](#molecules-from-external-chemistry-sources)
43
+ - [Chemical reactions](#chemical-reactions)
44
+ - [Balancing equations](#balancing-equations)
45
+ - [Mixing ChemQL with Python](#mixing-chemql-with-python)
46
+ - [Multiline Python blocks](#multiline-python-blocks)
47
+ - [Running shell commands](#running-shell-commands)
48
+ - [Comments, semicolons, and line
49
+ continuation](#comments-semicolons-and-line-continuation)
50
+ - [Scripts, pipes, and output files](#scripts-pipes-and-output-files)
51
+ - [Session history and exports](#session-history-and-exports)
52
+ - [Terminal experience](#terminal-experience)
53
+ - [Python API](#python-api)
54
+ - [Query syntax reference](#query-syntax-reference)
55
+ - [Examples](#examples)
56
+ - [Troubleshooting](#troubleshooting)
57
+
58
+ ## Highlights
59
+
60
+ - **Three queryable chemistry sources:** `elements`, `molecules`, and
61
+ `reactions`.
62
+ - **Database-style filtering:** equality, inequality, numeric
63
+ comparisons, pattern matching, containment, and grouped Boolean
64
+ logic.
65
+ - **Useful result operations:** choose the first or last match, sort
66
+ ascending or descending, limit results, count matches, and project
67
+ selected fields.
68
+ - **Readable results:** one selected field returns a list; multiple
69
+ fields are formatted as a column-aligned table.
70
+ - **Quick lookups:** find elements by name or symbol, molecules by
71
+ name or formula, and reactions by name, identifier, or equation.
72
+ - **External molecule lookup:** ChemQL can try local data first and
73
+ then use online chemistry services, including PubChem and the NIST
74
+ Chemistry WebBook, when available.
75
+ - **Reaction exploration:** search reaction records and match
76
+ reactants against the current reaction conditions and catalysts.
77
+ - **Equation balancing:** balance reaction equations with smallest
78
+ positive integer coefficients.
79
+ - **Reaction conditions:** configure temperature, pressure, and
80
+ catalysts before running reaction matching.
81
+ - **Hybrid Python:** execute Python expressions and statements, retain
82
+ variables between commands, and embed ChemQL query results directly
83
+ inside Python.
84
+ - **Python control flow:** use `if`/`elif`/`else`, `for`, `while`,
85
+ `break`, and `continue` blocks.
86
+ - **Multiline Python:** use `[[[` ... `]]]` for a single multiline
87
+ Python block.
88
+ - **Integrated shell:** execute commands in a persistent Bash or
89
+ Windows Command Prompt session using backticks or fenced terminal
90
+ blocks.
91
+ - **Comments and convenient command composition:** use `//` comments,
92
+ `///` multiline comments, semicolon-separated commands, and
93
+ backslash line continuation.
94
+ - **Interactive assistance:** syntax highlighting, command completion,
95
+ built-in help, and a browser-based periodic-table viewer.
96
+ - **Scriptable CLI:** run a command, run a file, pipe input through
97
+ standard input, disable ANSI escape sequences, or save clean output
98
+ to a file.
99
+ - **Execution-history exports:** save all, successful, or failed
100
+ queries and results.
101
+ - **Python integration:** import the query API and build queries
102
+ programmatically.
103
+ - **Upgrade helper:** request the latest release or a particular
104
+ version from the CLI.
105
+
106
+ ## Installation
107
+
108
+ Install the Python package from PyPI:
109
+
110
+ ``` bash
111
+ pip install chemql-python
112
+ ```
113
+
114
+ ## Upgrading the package or switching versions
115
+
116
+ If your chemql-python version is >=1.0.1, you can simply run
117
+ ```bash
118
+ chemql --upgrade
119
+ ```
120
+ Or to switch versions to for example 0.2.2
121
+ ```bash
122
+ chemql --upgrade 0.2.2
123
+ ```
124
+ However if you do not have chemql-python version >=1.0.1
125
+ ```bash
126
+ pip install --upgrade chemql-python
127
+ ```
128
+ Or to switch versions to for example 0.2.2
129
+ ```bash
130
+ pip install --force-reinstall chemql-python==0.2.2
131
+ ```
132
+ 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
133
+ ```bash
134
+ chemql --upgrade --force
135
+ ```
136
+ OR
137
+ ```bash
138
+ chemql --upgrade --dangerously
139
+ ```
140
+ Else
141
+ ```bash
142
+ pip install --upgrade chemql-python --break-system-packages
143
+ ```
144
+
145
+ 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`
146
+
147
+ ## Starting ChemQL
148
+
149
+ Start the interactive prompt:
150
+
151
+ ``` bash
152
+ chemql
153
+ ```
154
+
155
+ At the prompt, type `help` or `?` to see the built-in command reference.
156
+ Type `exit` or press `Ctrl+C` to leave.
157
+
158
+ Check the installed version:
159
+
160
+ ``` bash
161
+ chemql --version
162
+ ```
163
+
164
+ You can also use the language as a one-off command:
165
+
166
+ ``` bash
167
+ chemql -c 'search elements name = "Hydrogen"'
168
+ ```
169
+
170
+ ## Your first queries
171
+
172
+ ChemQL has three main sources. Specify the source in a query:
173
+
174
+ ``` text
175
+ search elements
176
+ search molecules
177
+ search reactions
178
+ ```
179
+
180
+ A source can be selected for subsequent searches:
181
+
182
+ ``` text
183
+ source elements
184
+ search name = "Hydrogen"
185
+ search number = 1
186
+ ```
187
+
188
+ You can always state a source explicitly:
189
+
190
+ ``` text
191
+ search elements name = "Hydrogen"
192
+ search molecules formula = "H2O"
193
+ search reactions reaction_type = "combustion"
194
+ ```
195
+
196
+ To list the available fields for the active source---or the fields
197
+ across all sources when no source is selected---use:
198
+
199
+ ``` text
200
+ list all
201
+ ```
202
+
203
+ ## Sources and data fields
204
+
205
+ ChemQL ships with local JSON datasets for its chemistry sources. Exact
206
+ records and fields depend on the bundled dataset version.
207
+
208
+ ### Elements
209
+
210
+ The element records include fields such as:
211
+
212
+ `name`, `symbol`, `number`, `atomic_mass`, `appearance`, `category`,
213
+ `phase`, `density`, `melt`, `boil`, `molar_heat`, `period`, `group`,
214
+ `block`, `shells`, `electron_configuration`,
215
+ `electron_configuration_semantic`, `electron_affinity`,
216
+ `electronegativity_pauling`, `ionization_energies`, `discovered_by`,
217
+ `named_by`, `summary`, `source`, `image`, `bohr_model_image`,
218
+ `bohr_model_3d`, `spectral_img`, `xpos`, `ypos`, `wxpos`, `wypos`, and
219
+ `cpk-hex`.
220
+
221
+ Example:
222
+
223
+ ``` text
224
+ search elements symbol = "Fe" return name symbol number atomic_mass
225
+ search elements phase = "Gas" return name symbol
226
+ search elements electronegativity_pauling > 3 return name symbol electronegativity_pauling
227
+ ```
228
+
229
+ The element `number` field is the atomic number.
230
+
231
+ ### Molecules
232
+
233
+ Molecule records include:
234
+
235
+ `name`, `formula`, `elements`, `molecular_weight`, `iupac_name`,
236
+ `smiles`, `cid`, `melting_point`, `boiling_point`, `density`, `state`,
237
+ `bonds`, and `total_bond_energy`.
238
+
239
+ Example:
240
+
241
+ ``` text
242
+ search molecules formula = "H2O"
243
+ search molecules molecular_weight < 50 return name formula molecular_weight
244
+ search molecules state = "Liquid" return name formula
245
+ ```
246
+
247
+ Bond information and calculated total bond energy are available when
248
+ present in the bundled bond datasets.
249
+
250
+ ### Reactions
251
+
252
+ Reaction records include:
253
+
254
+ `id`, `name`, `equation`, `reaction_type`, `reversible`, `reactants`,
255
+ `products`, `conditions`, `notes`, and `source`.
256
+
257
+ Example:
258
+
259
+ ``` text
260
+ search reactions reaction_type = "combustion"
261
+ search reactions reversible = true return name equation
262
+ search reactions name like "*Haber*" return name equation source
263
+ ```
264
+
265
+ ## Filtering and query logic
266
+
267
+ ChemQL supports the following comparison and matching operators:
268
+
269
+ -------------------------------------------------------------------------------------------
270
+ Operator Meaning Example
271
+ ----------------------- ----------------------- -------------------------------------------
272
+ `=` Equal `search elements symbol = "O"`
273
+
274
+ `!=` Not equal `search elements phase != "Gas"`
275
+
276
+ `>` Greater than `search molecules molecular_weight > 100`
277
+
278
+ `<` Less than `search elements number < 10`
279
+
280
+ `>=` Greater than or equal `search elements number >= 90`
281
+
282
+ `<=` Less than or equal `search molecules molecular_weight <= 20`
283
+
284
+ `like` Case-insensitive `search molecules name like "*water*"`
285
+ wildcard pattern
286
+
287
+ `like!` Case-sensitive wildcard `search elements name like! "Hydrogen"`
288
+ pattern
289
+
290
+ `likep` Pattern matching with `search molecules formula likep "*H*"`
291
+ the parser's pattern
292
+ mode
293
+
294
+ `has` Check whether a value `search molecules elements has "O"`
295
+ contains an item
296
+ -------------------------------------------------------------------------------------------
297
+
298
+ Use `and` and `or` to combine conditions:
299
+
300
+ ``` text
301
+ search elements number > 10 and number < 20
302
+ search molecules name like "*acid*" or name like "*base*"
303
+ ```
304
+
305
+ Parentheses let you group conditions:
306
+
307
+ ``` text
308
+ search molecules (name like "*water*" or formula = "H2O") and molecular_weight < 25
309
+ ```
310
+
311
+ Patterns are useful when you only know part of a name or formula. For
312
+ exact supported pattern behavior, try a query against the local dataset
313
+ and inspect the results.
314
+
315
+ ## Sorting, limiting, counting, and returning fields
316
+
317
+ These operations can be added to a search query.
318
+
319
+ ### Sort
320
+
321
+ ``` text
322
+ search elements sort number
323
+ search molecules sort molecular_weight desc
324
+ search reactions sort name asc
325
+ ```
326
+
327
+ Use `asc` for ascending or `desc` for descending order.
328
+
329
+ ### Limit
330
+
331
+ ``` text
332
+ search molecules limit 10
333
+ search elements number > 20 sort number limit 5
334
+ ```
335
+
336
+ ### Count
337
+
338
+ ``` text
339
+ search molecules count
340
+ search reactions reversible = true count
341
+ ```
342
+
343
+ ### First and last
344
+
345
+ ``` text
346
+ search elements first number > 10
347
+ search elements last number < 20
348
+ ```
349
+
350
+ You can also put `first` or `last` immediately after `search`:
351
+
352
+ ``` text
353
+ search first elements number > 10
354
+ search last molecules molecular_weight < 100
355
+ ```
356
+
357
+ ### Return only selected fields
358
+
359
+ A single field returns a one-dimensional list. Multiple fields return a
360
+ table.
361
+
362
+ ``` text
363
+ search molecules molecular_weight < 20 return name
364
+ search molecules molecular_weight < 20 return name formula molecular_weight
365
+ search reactions reversible = true return name equation source
366
+ ```
367
+
368
+ Filtering and result operations can be combined:
369
+
370
+ ``` text
371
+ search elements number > 10 and number < 30 sort number desc limit 5 return name symbol number
372
+ ```
373
+
374
+ ### Set operations
375
+
376
+ Query results can be combined using `union` or `intersection`:
377
+
378
+ ``` text
379
+ search elements number < 10 union search elements number > 90
380
+ search molecules name like "*water*" intersection search molecules molecular_weight < 50
381
+ ```
382
+
383
+ These operations are useful when you want to combine or compare result
384
+ sets.
385
+
386
+ ## Quick lookup commands
387
+
388
+ ### Find an element
389
+
390
+ ``` text
391
+ findel "He"
392
+ findel "Hydrogen"
393
+ ```
394
+
395
+ `findel` searches element names and symbols.
396
+
397
+ ### Find a molecule
398
+
399
+ ``` text
400
+ findmol "H2O"
401
+ findmol "Water"
402
+ findmol "Caffeine" return name formula molecular_weight
403
+ ```
404
+
405
+ `findmol` checks the local molecule dataset first, then can try external
406
+ lookup if no local match is found.
407
+
408
+ ### Find a reaction
409
+
410
+ ``` text
411
+ findre "Haber process"
412
+ findre "RHEA:10000"
413
+ findre "H2 + N2"
414
+ findre "Haber process" return name equation source
415
+ ```
416
+
417
+ `findre` searches reaction names, identifiers, and equations.
418
+
419
+ ### View the periodic table
420
+
421
+ ``` text
422
+ view
423
+ ```
424
+
425
+ This opens ChemQL's bundled periodic-table page in your default browser.
426
+
427
+ ## Molecules from external chemistry sources
428
+
429
+ When a molecule is not found locally, ChemQL can attempt an online
430
+ lookup using external chemistry services such as **PubChem** and the
431
+ **NIST Chemistry WebBook**.
432
+
433
+ ``` text
434
+ findmol "acetone"
435
+ findmol "caffeine"
436
+ findmol "water"
437
+ ```
438
+
439
+ The lookup code can retrieve or derive properties including molecular
440
+ identifiers and basic chemical data; availability depends on the
441
+ external service, network access, and whether a matching record exists.
442
+ External lookup is not required for ordinary searches against the
443
+ bundled local dataset.
444
+
445
+ ## Chemical reactions
446
+
447
+ ChemQL can search stored reaction records and has commands for setting
448
+ reaction conditions before attempting to match reactants.
449
+
450
+ ### Set temperature
451
+
452
+ Temperature values support Celsius (`C`), Fahrenheit (`F`), and Kelvin
453
+ (`K`):
454
+
455
+ ``` text
456
+ set temperature 450K
457
+ set temperature 150C
458
+ set temperature 300F
459
+ set temperature standard
460
+ set temperature room
461
+ ```
462
+
463
+ `standard` corresponds to 0 °C; `room` corresponds to 25 °C.
464
+
465
+ ### Set pressure
466
+
467
+ Pressure values support Pa, N/m², Nm⁻², bar, and atm, as well as the
468
+ `standard` and `room` presets:
469
+
470
+ ``` text
471
+ set pressure 101325Pa
472
+ set pressure 2bar
473
+ set pressure 1atm
474
+ set pressure standard
475
+ set pressure room
476
+ ```
477
+
478
+ The presets use 100000 Pa for `standard` and 101325 Pa for `room`.
479
+
480
+ ### Configure catalysts
481
+
482
+ ``` text
483
+ set catalysts iron zinc
484
+ add catalyst "Vanadium oxide"
485
+ remove catalyst "Vanadium oxide"
486
+ set catalysts
487
+ ```
488
+
489
+ `set catalysts` with no values clears the catalyst list. `add catalyst`
490
+ adds a catalyst if it is not already present; `remove catalyst` removes
491
+ a matching catalyst.
492
+
493
+ ### Inspect current conditions
494
+
495
+ ``` text
496
+ conditions
497
+ ```
498
+
499
+ Unset temperature or pressure values are shown as not set.
500
+
501
+ ### Match reactants
502
+
503
+ ``` text
504
+ react N2 3H2
505
+ ```
506
+
507
+ `react` attempts to find a matching reaction using the supplied
508
+ reactants and the current reaction conditions. The implementation uses a
509
+ temperature tolerance of 5 K and a pressure tolerance of 5% for reaction
510
+ matching. A match depends on the available reaction records and their
511
+ conditions.
512
+
513
+ ## Balancing equations
514
+
515
+ Use `balance` to balance a chemical equation:
516
+
517
+ ``` text
518
+ balance H2 + O2 -> H2O
519
+ balance Fe + O2 -> Fe2O3
520
+ balance N2 + H2 <-> NH3
521
+ ```
522
+
523
+ - `->` represents an irreversible reaction.
524
+ - `<->` represents a reversible reaction.
525
+ - ChemQL aims to return the smallest positive integer coefficients.
526
+
527
+ The result is represented as a reaction object, which can also be
528
+ queried or inspected from Python.
529
+
530
+ ## Mixing ChemQL with Python
531
+
532
+ ChemQL is a hybrid language: a single-line Python expression or
533
+ statement can be enclosed in square brackets.
534
+
535
+ ``` text
536
+ [x = 10]
537
+ [print(x)]
538
+ [x * 2]
539
+ ```
540
+
541
+ Python variables persist for the session, so later blocks can use values
542
+ created earlier.
543
+
544
+ ``` text
545
+ [import math]
546
+ [radius = 5]
547
+ [area = math.pi * radius**2]
548
+ [print(area)]
549
+ ```
550
+
551
+ Python's built-in namespace is available, and `math` is preloaded.
552
+ **Only run Python or shell code you trust**: these blocks execute real
553
+ code, not a sandboxed query language.
554
+
555
+ ### Embed ChemQL queries in Python
556
+
557
+ Use `{{ ... }}` to run a ChemQL query and insert its result into Python
558
+ code:
559
+
560
+ ``` text
561
+ [hydrogen = {{ search elements name = "Hydrogen" }}]
562
+ [print(hydrogen)]
563
+ ```
564
+
565
+ A query block can also be used on its own as a value-producing
566
+ expression:
567
+
568
+ ``` text
569
+ {{ search molecules molecular_weight < 20 return name formula }}
570
+ ```
571
+
572
+ This is useful when you want ChemQL to find data and Python to
573
+ calculate, transform, or display something using that data.
574
+
575
+ ### Python control-flow blocks
576
+
577
+ ChemQL supports block-style Python control flow:
578
+
579
+ ``` text
580
+ [if value > 10]
581
+ [print("Large")]
582
+ [elif value == 10]
583
+ [print("Exactly ten")]
584
+ [else]
585
+ [print("Small")]
586
+ [endblock]
587
+ ```
588
+
589
+ Loop example:
590
+
591
+ ``` text
592
+ [for element in {{ search elements number < 5 }}]
593
+ [print(element.name, element.symbol)]
594
+ [endblock]
595
+ ```
596
+
597
+ A `while` block is also supported:
598
+
599
+ ``` text
600
+ [i = 0]
601
+ [while i < 3]
602
+ [print(i)]
603
+ [i += 1]
604
+ [endblock]
605
+ ```
606
+
607
+ Use `[break]` and `[continue]` inside loops. As with ordinary Python,
608
+ make sure a `while` loop has a condition that eventually becomes false
609
+ unless you intentionally want it to continue.
610
+
611
+ ### Multiline Python blocks
612
+
613
+ For longer Python code, use `[[[` to start a block and a line containing
614
+ `]]]` to finish it:
615
+
616
+ ``` text
617
+ [[[
618
+ values = {{ search elements number < 10 return name }}
619
+ for value in values:
620
+ print(value)
621
+ ]]]
622
+ ```
623
+
624
+ ChemQL executes the block as one Python unit and captures its printed
625
+ output as one result. Keep the closing `]]]` on its own line.
626
+
627
+ ## Running shell commands
628
+
629
+ ChemQL can run shell commands using backticks. It keeps a shell session
630
+ alive so commands can share shell state.
631
+
632
+ ``` text
633
+ `echo Hello from the shell`
634
+ `pwd`
635
+ ```
636
+
637
+ For a multiline command, use a fenced block. The opening fence can
638
+ optionally name a shell:
639
+
640
+ ```` text
641
+ ```bash
642
+ echo "First line"
643
+ echo "Second line"
644
+ ```
645
+ ````
646
+
647
+ Windows users can use a `cmd` fence:
648
+
649
+ ```` text
650
+ ```cmd
651
+ echo Hello from Windows
652
+ ver
653
+ ```
654
+ ````
655
+
656
+ Supported opening forms include a plain triple-backtick fence and fences
657
+ labelled `bash`, `sh`, `cmd`, or `terminal`. Close the block with a line
658
+ containing three backticks.
659
+
660
+ **Security note:** shell blocks run real operating-system commands with
661
+ your user's permissions. Review commands before executing them,
662
+ especially commands copied from untrusted sources.
663
+
664
+ ## Comments, semicolons, and line continuation
665
+
666
+ ### Single-line comments
667
+
668
+ Use `//` for comments:
669
+
670
+ ``` text
671
+ search elements number < 10 // The first nine elements
672
+ ```
673
+
674
+ The comment marker is intended to be recognized outside quoted strings.
675
+
676
+ ### Multiline comments
677
+
678
+ Use `///` to begin and end a multiline comment:
679
+
680
+ ``` text
681
+ /// This is a comment.
682
+ It can continue across multiple lines.
683
+ The whole comment is ignored. ///
684
+ search elements symbol = "O"
685
+ ```
686
+
687
+ A multiline comment can also be written with opening and closing markers
688
+ on the same line.
689
+
690
+ ### Semicolon-separated commands
691
+
692
+ Run multiple ChemQL commands on one line with semicolons:
693
+
694
+ ``` text
695
+ source elements; search name = "Hydrogen"; search number = 8
696
+ ```
697
+
698
+ ChemQL's command splitter tracks quotes and bracketed/query expressions
699
+ so semicolons inside quoted strings or protected blocks are not treated
700
+ as command separators.
701
+
702
+ ### Line continuation
703
+
704
+ End a line with `\` to continue the command on the next line:
705
+
706
+ ``` text
707
+ search elements \
708
+ number > 10 and \
709
+ number < 20 \
710
+ sort number desc \
711
+ limit 5
712
+ ```
713
+
714
+ The continued lines are treated as one command.
715
+
716
+ ## Scripts, pipes, and output files
717
+
718
+ ### Run a command
719
+
720
+ ``` bash
721
+ chemql -c 'search elements symbol = "O"'
722
+ ```
723
+
724
+ ### Run a file
725
+
726
+ Save commands in a `.cql` or `.chemql` file, for example `explore.cql`:
727
+
728
+ ``` text
729
+ search elements number < 10 return name symbol number
730
+ search molecules molecular_weight < 50 sort molecular_weight return name formula molecular_weight
731
+ ```
732
+
733
+ Run it:
734
+
735
+ ``` bash
736
+ chemql -f explore.cql
737
+ ```
738
+
739
+ Both `.cql` and `.chemql` are suitable file extensions; the CLI accepts
740
+ a file path.
741
+
742
+ ### Pipe commands through standard input
743
+
744
+ ``` bash
745
+ echo 'search elements symbol = "O"' | chemql
746
+ ```
747
+
748
+ You can also pipe a multi-line script into ChemQL:
749
+
750
+ ``` bash
751
+ cat explore.cql | chemql
752
+ ```
753
+
754
+ On Windows PowerShell, use `Get-Content explore.cql | chemql` or
755
+ redirect a file into the command.
756
+
757
+ ### Disable ANSI escape sequences
758
+
759
+ ``` bash
760
+ chemql --no-ansi -c 'search elements symbol = "O"'
761
+ ```
762
+
763
+ This is useful when redirecting output to logs or processing it with
764
+ other tools.
765
+
766
+ ### Write clean output to a file
767
+
768
+ Use `-o` / `--output` together with `-c` or `-f`:
769
+
770
+ ``` bash
771
+ chemql -c 'search elements number < 10 return name symbol' -o elements.txt
772
+ chemql -f explore.cql --output results.txt
773
+ ```
774
+
775
+ The output file is written without ANSI escape sequences. `-o` requires
776
+ either `-c` or `-f`.
777
+
778
+ ## Session history and exports
779
+
780
+ ChemQL records queries and results processed during the session. Use
781
+ `dump` to export that history to a UTF-8 text file.
782
+
783
+ ``` text
784
+ dump session.txt
785
+ dump all session.txt
786
+ dump good session-successes.txt
787
+ dump bad session-errors.txt
788
+ dump all queries queries.txt
789
+ dump good results successful-results.txt
790
+ dump bad results failed-results.txt
791
+ ```
792
+
793
+ Available forms:
794
+
795
+ Command What it exports
796
+ -------------------------- ------------------------------------
797
+ `dump FILE` All recorded queries and results
798
+ `dump all FILE` All recorded queries and results
799
+ `dump good FILE` Successful executions
800
+ `dump bad FILE` Failed executions
801
+ `dump all queries FILE` All recorded queries only
802
+ `dump good queries FILE` Successful queries only
803
+ `dump bad queries FILE` Failed queries only
804
+ `dump all results FILE` All results only
805
+ `dump good results FILE` Results from successful executions
806
+ `dump bad results FILE` Results from failed executions
807
+
808
+ The `good` and `bad` categories use ChemQL's execution-status tracking.
809
+ Shell command exit codes are not necessarily equivalent to ChemQL's own
810
+ error tracking.
811
+
812
+ ## Terminal experience
813
+
814
+ In interactive mode, ChemQL provides:
815
+
816
+ - **Syntax highlighting** for ChemQL commands, operators, fields,
817
+ strings, and related syntax.
818
+ - **Tab completion** for commands, sources, fields, and context-aware
819
+ suggestions.
820
+ - **Built-in help** through `help` or `?`.
821
+ - **A periodic-table viewer** through `view`.
822
+ - **ANSI styling** for readable terminal output, with `--no-ansi`
823
+ available for plain output.
824
+ - **Persistent Python variables** across Python blocks.
825
+ - **A persistent shell session** for backtick and fenced shell
826
+ commands.
827
+ - **Friendly exit controls:** type `exit` or press `Ctrl+C`.
828
+
829
+ ## Python API
830
+
831
+ ChemQL can also be used from Python. The public query function is
832
+ `execute_query_text()`:
833
+
834
+ ``` python
835
+ from chemql import execute_query_text
836
+
837
+ result = execute_query_text('search elements name = "Hydrogen"')
838
+ print(result)
839
+ ```
840
+
841
+ `execute_query_text()` accepts a query string and returns its query
842
+ result. Depending on the query, that result may be a chemistry object,
843
+ list, table-like result, count, string, or `None`.
844
+
845
+ The higher-level `execute_query()` wrapper is also available:
846
+
847
+ ``` python
848
+ from chemql import execute_query
849
+
850
+ result = execute_query('search molecules formula = "H2O"')
851
+ print(result)
852
+ ```
853
+
854
+ The package exposes chemistry classes such as `Element`, `Molecule`, and
855
+ `Reaction`, as well as helper functions including `search`, `union`, and
856
+ `intersection`. Public APIs can evolve between versions; consult the
857
+ installed source and `help()` for the exact version you use.
858
+
859
+ ## Query syntax reference
860
+
861
+ A typical query follows this pattern:
862
+
863
+ ``` text
864
+ search [first|last|all] SOURCE [conditions] [sort FIELD [asc|desc]] [limit N] [count] [return FIELD ...]
865
+ ```
866
+
867
+ Examples:
868
+
869
+ ``` text
870
+ search elements number = 8
871
+ search molecules name like "*acid*" sort molecular_weight limit 10
872
+ search reactions reversible = true return name equation
873
+ ```
874
+
875
+ Common commands:
876
+
877
+ Command Purpose
878
+ ------------------------- -------------------------------------
879
+ `search ...` Query a source
880
+ `source NAME` Set the current source
881
+ `list all` List fields
882
+ `findel VALUE` Find an element
883
+ `findmol VALUE` Find a molecule
884
+ `findre VALUE` Find a reaction
885
+ `react ...` Match reactants to stored reactions
886
+ `balance ...` Balance a chemical equation
887
+ `set temperature VALUE` Set reaction temperature
888
+ `set pressure VALUE` Set reaction pressure
889
+ `set catalysts ...` Replace the catalyst list
890
+ `add catalyst NAME` Add a catalyst
891
+ `remove catalyst NAME` Remove a catalyst
892
+ `conditions` Show reaction conditions
893
+ `view` Open the periodic-table viewer
894
+ `dump ...` Export execution history
895
+ `clear` Clear the terminal
896
+ `help` / `?` Show help
897
+ `version` Print the ChemQL version
898
+ `exit` Leave the interactive prompt
899
+
900
+ ## Examples
901
+
902
+ ### Find noble gases
903
+
904
+ ``` text
905
+ search elements category like "*noble gas*" return name symbol number
906
+ ```
907
+
908
+ ### Find relatively light molecules
909
+
910
+ ``` text
911
+ search molecules molecular_weight < 50 sort molecular_weight asc limit 10 return name formula molecular_weight
912
+ ```
913
+
914
+ ### Find reactions of a particular type
915
+
916
+ ``` text
917
+ search reactions reaction_type = "combustion" return name equation reversible
918
+ ```
919
+
920
+ ### Explore and export a session
921
+
922
+ ``` text
923
+ search elements number < 20 return name symbol number
924
+ search molecules molecular_weight < 100 return name formula molecular_weight
925
+ dump all results chemistry-results.txt
926
+ ```
927
+
928
+ ### Combine a query with Python
929
+
930
+ ``` text
931
+ [light_molecules = {{ search molecules molecular_weight < 50 return name }}]
932
+ [print("Found names:", light_molecules)]
933
+ ```
934
+
935
+ ### Use ChemQL from a Python script
936
+
937
+ ``` python
938
+ from chemql import execute_query_text
939
+
940
+ elements = execute_query_text(
941
+ 'search elements number < 10 return name symbol'
942
+ )
943
+ print(elements)
944
+ ```
945
+
946
+ ## Troubleshooting
947
+
948
+ - **`No source selected`:** specify a source in the query, such as
949
+ `search elements ...`, or set one with `source elements`.
950
+ - **Unknown field:** run `list all` after selecting a source to see
951
+ its available field names. Use `number` for an element's atomic
952
+ number in the current data model.
953
+ - **No local molecule match:** `findmol` may try online lookup, which
954
+ requires network access and an available external service.
955
+ - **Output contains terminal escape codes:** add `--no-ansi` or use
956
+ `-o FILE` with `-c` or `-f`.
957
+ - **A multiline block is incomplete:** close a Python block with `]]]`
958
+ on its own line or a terminal block with three backticks on its own
959
+ line.
960
+ - **Python or shell command behaves unexpectedly:** remember that
961
+ these execute real code in your environment. Check quotes,
962
+ indentation, and the exact command before running it.
963
+ - **A reaction does not match:** check the available reaction records,
964
+ the reactant spelling and stoichiometry, and the temperature,
965
+ pressure, and catalyst settings.
966
+
967
+ ## Safety and scope
968
+
969
+ ChemQL is a chemistry data/query tool, not a replacement for
970
+ authoritative chemical references, laboratory procedures, or
971
+ professional safety guidance. Dataset coverage and online service
972
+ responses may be incomplete. Validate important scientific results
973
+ against appropriate primary or authoritative sources.
974
+
975
+ Python and shell blocks execute real code with your operating-system
976
+ user's permissions. Do not run scripts or commands you do not trust.
977
+
978
+ ## License
979
+
980
+ [MIT License](https://github.com/rakibulofficial1017/ChemQL/blob/main/LICENSE)
981
+
982
+ Created by [Mohammad Rakibul Islam](https://github.com/rakibulofficial1017).
983
+ Source code: [rakibulofficial1017/ChemQL](https://github.com/rakibulofficial1017/ChemQL).
984
+
985
+