chemql-python 1.3.0__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.
Files changed (24) hide show
  1. {chemql_python-1.3.0/src/chemql_python.egg-info → chemql_python-1.3.1}/PKG-INFO +2 -2
  2. {chemql_python-1.3.0 → chemql_python-1.3.1}/README.md +1 -1
  3. {chemql_python-1.3.0 → chemql_python-1.3.1}/pyproject.toml +1 -1
  4. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/__init__.py +175 -7
  5. {chemql_python-1.3.0 → chemql_python-1.3.1/src/chemql_python.egg-info}/PKG-INFO +2 -2
  6. {chemql_python-1.3.0 → chemql_python-1.3.1}/LICENSE +0 -0
  7. {chemql_python-1.3.0 → chemql_python-1.3.1}/setup.cfg +0 -0
  8. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/__main__.py +0 -0
  9. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/BondEnergies.json +0 -0
  10. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/MoleculeBonds.json +0 -0
  11. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/Molecules.json +0 -0
  12. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/PeriodicTableJSON.json +0 -0
  13. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/Reactions.json +0 -0
  14. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
  15. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
  16. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql/html/periodic_table.html +0 -0
  17. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql_python.egg-info/SOURCES.txt +0 -0
  18. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql_python.egg-info/dependency_links.txt +0 -0
  19. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql_python.egg-info/entry_points.txt +0 -0
  20. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql_python.egg-info/requires.txt +0 -0
  21. {chemql_python-1.3.0 → chemql_python-1.3.1}/src/chemql_python.egg-info/top_level.txt +0 -0
  22. {chemql_python-1.3.0 → chemql_python-1.3.1}/tests/test_external_molecule_lookup.py +0 -0
  23. {chemql_python-1.3.0 → chemql_python-1.3.1}/tests/test_public_api.py +0 -0
  24. {chemql_python-1.3.0 → chemql_python-1.3.1}/tests/test_reactions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chemql-python
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: A chemistry-focused query language and REPL
5
5
  Author-email: Mohammad Rakibul Islam <rakibulofficial1017@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -19,7 +19,7 @@ SQL-inspired syntax, inspect elements and molecules, look up reactions,
19
19
  balance equations, and combine chemistry queries with Python and shell
20
20
  commands.
21
21
 
22
- - **Version:** `1.3.0`
22
+ - **Version:** `1.3.1`
23
23
  - **PyPI distribution:** `chemql-python`
24
24
  - **Python import / CLI name:** `chemql`
25
25
  - **Author:** Mohammad Rakibul Islam
@@ -6,7 +6,7 @@ SQL-inspired syntax, inspect elements and molecules, look up reactions,
6
6
  balance equations, and combine chemistry queries with Python and shell
7
7
  commands.
8
8
 
9
- - **Version:** `1.3.0`
9
+ - **Version:** `1.3.1`
10
10
  - **PyPI distribution:** `chemql-python`
11
11
  - **Python import / CLI name:** `chemql`
12
12
  - **Author:** Mohammad Rakibul Islam
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "chemql-python"
7
- version = "1.3.0"
7
+ version = "1.3.1"
8
8
  authors = [
9
9
  { name = "Mohammad Rakibul Islam", email = "rakibulofficial1017@gmail.com" }
10
10
  ]
@@ -52,7 +52,7 @@ __all__ = [
52
52
  "__version__"
53
53
  ]
54
54
 
55
- __version__ = "1.3.0"
55
+ __version__ = "1.3.1"
56
56
 
57
57
  # Persistent preprocessor/function state for the current ChemQL session.
58
58
  DEFINITIONS = {}
@@ -2034,7 +2034,7 @@ def _reaction_api_json(url, timeout=REACTION_API_TIMEOUT):
2034
2034
  request = urllib.request.Request(
2035
2035
  url,
2036
2036
  headers={
2037
- "User-Agent": "ChemQL/1.3.0 (reaction lookup; contact: chemql-user)",
2037
+ "User-Agent": f"ChemQL/{__version__} (reaction lookup; contact: chemql-user)",
2038
2038
  "Accept": "application/json",
2039
2039
  },
2040
2040
  )
@@ -2050,7 +2050,7 @@ def _reaction_api_text(url, timeout=REACTION_API_TIMEOUT):
2050
2050
  request = urllib.request.Request(
2051
2051
  url,
2052
2052
  headers={
2053
- "User-Agent": "ChemQL/1.3.0 (reaction lookup; contact: chemql-user)",
2053
+ "User-Agent": f"ChemQL/{__version__} (reaction lookup; contact: chemql-user)",
2054
2054
  "Accept": "text/tab-separated-values,text/plain,*/*",
2055
2055
  },
2056
2056
  )
@@ -4045,7 +4045,7 @@ def process_lines(lines):
4045
4045
  print(output, end="" if output.endswith("\n") else "\n")
4046
4046
  _record_execution("[[[\n" + code + "\n]]]", output, True)
4047
4047
  except Exception as exc:
4048
- message = f"Error: {exc}"
4048
+ message = f"\033[31mError: {exc}\033[0m"
4049
4049
  print(strip_ansi(message) if NO_ANSI else message, file=sys.stderr)
4050
4050
  _record_execution("[[[\n" + code + "\n]]]", message, False)
4051
4051
  i += 1
@@ -4164,7 +4164,7 @@ def process_lines(lines):
4164
4164
  except Exception as exc:
4165
4165
  if _CHEMQL_RISK_DEPTH:
4166
4166
  raise
4167
- message = f"Error: {exc}"
4167
+ message = f"\033[31mError: {exc}\033[0m"
4168
4168
  print(strip_ansi(message) if NO_ANSI else message, file=sys.stderr)
4169
4169
  _record_execution(command, message, False)
4170
4170
 
@@ -4766,7 +4766,175 @@ def execute(arguments, query_text=None, positions=None):
4766
4766
 
4767
4767
  return format_error(f"Unknown command `{arguments[0]}`")
4768
4768
 
4769
- HELP = '\x1b[1;94m╭──────────────────────────────────────────────────────────────────────────────╮\x1b[0m\n\x1b[1;94m│\x1b[0m \x1b[1;96m✦ \x1b[1mChemQL\x1b[0m \x1b[97mv1.2.0\x1b[0m \x1b[90m│\x1b[0m \x1b[1m\x1b[97mTHE PYTHON CHEMISTRY QUERY LANGUAGE\x1b[0m \x1b[1;94m│\x1b[0m\n\x1b[1;94m│\x1b[0m \x1b[90mQuery chemical datasets · balance equations · embed Python · automate workflows\x1b[0m \x1b[1;94m│\x1b[0m\n\x1b[1;94m╰──────────────────────────────────────────────────────────────────────────────╯\x1b[0m\n\n\x1b[1;93m\x1b[1m▶ QUICK START\x1b[0m\n \x1b[92msearch elements ... \x1b[0m \x1b[90m│\x1b[0m Query the periodic-table dataset\n \x1b[92msearch molecules ... \x1b[0m \x1b[90m│\x1b[0m Query molecule records\n \x1b[92msearch reactions ... \x1b[0m \x1b[90m│\x1b[0m Query stored reaction records\n \x1b[92mfindel "He" \x1b[0m \x1b[90m│\x1b[0m Find an element by name or symbol\n \x1b[92mfindmol "Water" \x1b[0m \x1b[90m│\x1b[0m Find a molecule by name or formula\n \x1b[92mfindre "Haber process" \x1b[0m \x1b[90m│\x1b[0m Find a reaction by name, ID, or equation\n \x1b[92mlist all \x1b[0m \x1b[90m│\x1b[0m List available fields and sources\n \x1b[92mhelp or ? \x1b[0m \x1b[90m│\x1b[0m Show this help reference\n \x1b[92mversion \x1b[0m \x1b[90m│\x1b[0m Show the installed version\n \x1b[92mexit \x1b[0m \x1b[90m│\x1b[0m Leave the interactive prompt\n\n\x1b[1;93m\x1b[1m◆ QUERY SOURCES & EXAMPLES\x1b[0m\n \x1b[92msearch elements [where] \x1b[0m \x1b[90m│\x1b[0m Search element data\n \x1b[92msearch molecules [where] \x1b[0m \x1b[90m│\x1b[0m Search molecule data\n \x1b[92msearch reactions [where] \x1b[0m \x1b[90m│\x1b[0m Search reaction data\n \x1b[1;96msource elements|molecules|reactions\x1b[0m \x1b[90m│\x1b[0m Set the current source\n \x1b[95msearch elements symbol = "Fe" return name symbol number atomic_mass\x1b[0m\n \x1b[95msearch molecules molecular_weight < 50 sort molecular_weight limit 10\x1b[0m\n \x1b[95msearch reactions reversible = true return name equation source\x1b[0m\n\n\x1b[1;93m\x1b[1m◆ FILTERS & LOGIC\x1b[0m\n \x1b[1;96m= != > < >= <= \x1b[0m \x1b[90m│\x1b[0m Comparison operators\n \x1b[1;96mlike / like! \x1b[0m \x1b[90m│\x1b[0m Case-insensitive / case-sensitive wildcard matching\n \x1b[1;96mlikep / has \x1b[0m \x1b[90m│\x1b[0m Pattern matching / contains an item\n \x1b[1;96mand / or / ( ... ) \x1b[0m \x1b[90m│\x1b[0m Combine conditions; parentheses group logic\n \x1b[95msearch elements number > 10 and number < 20\x1b[0m\n \x1b[95msearch molecules name like "*water*"\x1b[0m\n \x1b[95msearch molecules (name like "*water*" or formula = "H2O") and molecular_weight < 25\x1b[0m\n\n\x1b[1;93m\x1b[1m◆ RESULT OPERATIONS\x1b[0m\n \x1b[92mfirst / last \x1b[0m \x1b[90m│\x1b[0m Return the first or last match\n \x1b[92msort FIELD [asc|desc] \x1b[0m \x1b[90m│\x1b[0m Sort matching records\n \x1b[92mlimit N \x1b[0m \x1b[90m│\x1b[0m Limit the number of results\n \x1b[92mcount \x1b[0m \x1b[90m│\x1b[0m Count matches\n \x1b[92mreturn FIELD ... \x1b[0m \x1b[90m│\x1b[0m Choose fields; one field lists, multiple fields form a table\n \x1b[92munion / intersection \x1b[0m \x1b[90m│\x1b[0m Combine result sets\n \x1b[95msearch molecules molecular_weight < 20 sort molecular_weight asc limit 5\x1b[0m\n \x1b[95msearch elements number < 10 union search elements number > 90\x1b[0m\n\n\x1b[1;93m\x1b[1m◆ REACTION TOOLS & CONDITIONS\x1b[0m\n \x1b[1;96mset temperature 723K|150C|300F|standard|room \x1b[0m \x1b[90m│\x1b[0m Set reaction temperature\n \x1b[1;96mset pressure 101325Pa|2bar|1atm|standard|room \x1b[0m \x1b[90m│\x1b[0m Set reaction pressure\n \x1b[1;96mset catalysts iron zinc \x1b[0m \x1b[90m│\x1b[0m Set the catalyst list\n \x1b[1;96mset catalysts \x1b[0m \x1b[90m│\x1b[0m Clear the catalyst list\n \x1b[1;96madd catalyst "Vanadium oxide"\x1b[0m \x1b[90m│\x1b[0m Add a catalyst\n \x1b[1;96mremove catalyst "Vanadium oxide"\x1b[0m \x1b[90m│\x1b[0m Remove a catalyst\n \x1b[1;96mconditions \x1b[0m \x1b[90m│\x1b[0m Show active temperature, pressure, and catalysts\n \x1b[1;96mreact N2 3H2 \x1b[0m \x1b[90m│\x1b[0m Find a stored reaction matching reactants\n \x1b[1;96mbalance H2 + O2 -> H2O \x1b[0m \x1b[90m│\x1b[0m Balance an irreversible equation\n \x1b[1;96mbalance N2 + H2 <-> NH3 \x1b[0m \x1b[90m│\x1b[0m Balance a reversible equation\n \x1b[2mTemperature units: C, F, K. Pressure units include Pa, N/m^2, Nm^-2, bar, and atm.\x1b[0m\n \x1b[2mPresets: standard = 0 C and 100000 Pa; room = 25 C and 101325 Pa.\x1b[0m\n\n\x1b[1;93m\x1b[1m◆ PREPROCESSOR, FUNCTIONS & MACROS · V1.2.0\x1b[0m\n \x1b[95mdefine MAX 9 \x1b[0m \x1b[90m│\x1b[0m Define a literal replacement used as @MAX\n \x1b[95mdefinitions \x1b[0m \x1b[90m│\x1b[0m List current literal definitions\n \x1b[95mremove definition MAX \x1b[0m \x1b[90m│\x1b[0m Remove a definition\n \x1b[95mdefine MAX 9\x1b[0m\n \x1b[95msearch elements number <= @MAX\x1b[0m\n\n \x1b[95mfunc square \x1b[0m \x1b[90m│\x1b[0m Begin a function; finish it with endfunc\n \x1b[95mreturn [\\1 * \\1] \x1b[0m \x1b[90m│\x1b[0m Return a value using positional argument \\1\n \x1b[95mendfunc \x1b[0m \x1b[90m│\x1b[0m Close the function definition\n \x1b[95msquare{5} \x1b[0m \x1b[90m│\x1b[0m Call the function with brace-delimited arguments\n\n \x1b[95mdefine light{} \x1b[0m \x1b[90m│\x1b[0m Begin a macro; finish it with enddefine\n \x1b[95msearch molecules molecular_weight < \\1 return name formula\x1b[0m\n \x1b[95menddefine \x1b[0m \x1b[90m│\x1b[0m Close the macro definition\n \x1b[95m@light{50} \x1b[0m \x1b[90m│\x1b[0m Expand and execute a macro\n \x1b[2mFunction and macro arguments use positional placeholders: \\1, \\2, and so on.\x1b[0m\n \x1b[2mDefinitions are processed in source order and are local to the current session.\x1b[0m\n\n\x1b[1;93m\x1b[1m◆ PYTHON INTEGRATION\x1b[0m\n \x1b[1;96m[x = 10] \x1b[0m \x1b[90m│\x1b[0m Execute a Python statement\n \x1b[1;96m[print(x)] \x1b[0m \x1b[90m│\x1b[0m Use Python variables across commands\n \x1b[1;96m[x * 2] \x1b[0m \x1b[90m│\x1b[0m Evaluate and display a Python expression\n \x1b[95m{{ search elements name = "Hydrogen" }}\x1b[0m\n \x1b[2mEmbedded {{ ... }} queries return their result as a value.\x1b[0m\n Python control-flow blocks:\n \x1b[95m[if condition] ... [elif condition] ... [else] ... [endblock]\x1b[0m\n \x1b[95m[for item in iterable] ... [endblock]\x1b[0m\n \x1b[95m[while condition] ... [endblock]\x1b[0m\n \x1b[95m[break] and [continue] inside loops\x1b[0m\n Multiline Python block:\n \x1b[95m[[[\x1b[0m\n \x1b[95mfor x in range(3):\x1b[0m\n \x1b[95m print(x)\x1b[0m\n \x1b[95m]]] # close on its own line\x1b[0m\n\n\x1b[1;93m\x1b[1m◆ SHELL, COMMENTS & COMMAND COMPOSITION\x1b[0m\n \x1b[1;96m`command` \x1b[0m \x1b[90m│\x1b[0m Run a command in the persistent system shell\n \x1b[1;96m```bash ... ``` \x1b[0m \x1b[90m│\x1b[0m Run a multiline shell block (also sh, cmd, terminal)\n \x1b[1;96m// comment \x1b[0m \x1b[90m│\x1b[0m Single-line comment\n \x1b[1;96m/// ... /// \x1b[0m \x1b[90m│\x1b[0m Multiline comment\n \x1b[1;96mcommand1; command2 \x1b[0m \x1b[90m│\x1b[0m Run multiple commands on one line\n \x1b[1;96mtrailing backslash \x1b[0m \x1b[90m│\x1b[0m Continue a command on the next line\n \x1b[1;96mview \x1b[0m \x1b[90m│\x1b[0m Open the bundled periodic-table viewer\n \x1b[1;96mclear \x1b[0m \x1b[90m│\x1b[0m Clear the terminal\n\n\x1b[1;93m\x1b[1m◆ HISTORY EXPORT\x1b[0m\n \x1b[92mdump FILE \x1b[0m \x1b[90m│\x1b[0m Export all recorded queries and results\n \x1b[92mdump all|good|bad FILE \x1b[0m \x1b[90m│\x1b[0m Export all, successful, or failed executions\n \x1b[92mdump all|good|bad queries FILE\x1b[0m \x1b[90m│\x1b[0m Export query history\n \x1b[92mdump all|good|bad results FILE\x1b[0m \x1b[90m│\x1b[0m Export result history\n\n\x1b[1;93m\x1b[1m◆ COMMAND-LINE OPTIONS\x1b[0m\n \x1b[1;96mchemql \x1b[0m \x1b[90m│\x1b[0m Start the interactive prompt\n \x1b[1;96mchemql -c "COMMAND" \x1b[0m \x1b[90m│\x1b[0m Execute one command\n \x1b[1;96mchemql -f FILE \x1b[0m \x1b[90m│\x1b[0m Execute commands from a file\n \x1b[1;96mchemql --version \x1b[0m \x1b[90m│\x1b[0m Print the installed version\n \x1b[1;96mchemql --no-ansi \x1b[0m \x1b[90m│\x1b[0m Disable ANSI styling in output\n \x1b[1;96mchemql -c "COMMAND" -o FILE \x1b[0m \x1b[90m│\x1b[0m Write command output to a plain-text file\n \x1b[1;96mchemql --upgrade [VERSION] \x1b[0m \x1b[90m│\x1b[0m Upgrade to latest or a chosen release\n \x1b[1;96mchemql --force \x1b[0m \x1b[90m│\x1b[0m Force upgrade past system-package protections\n\n\x1b[1;93m\x1b[1m◆ PYTHON API\x1b[0m\n \x1b[95mfrom chemql import execute_query_text, execute_query\x1b[0m\n \x1b[95mresult = execute_query_text(\'search elements symbol = "O"\')\x1b[0m\n \x1b[2mDistribution package: chemql-python · import / CLI name: chemql\x1b[0m\n\n\x1b[1;93m\x1b[1m⚠ SAFETY & DATA NOTES\x1b[0m\n \x1b[2mPython blocks and shell commands run real code with your user permissions.\x1b[0m\n \x1b[2mRun only code and commands you trust. External lookups need network access\x1b[0m\n \x1b[2mand can fail when a remote service is unavailable.\x1b[0m\n\n\x1b[1;94m────────────────────────────────────────────────────────────────────────────────\x1b[0m\n\x1b[90mChemQL 1.2.0 · Type \x1b[92mhelp\x1b[90m for this guide, or \x1b[92mexit\x1b[90m to quit.\x1b[0m\n'
4769
+
4770
+ HELP = (
4771
+ "\x1b[1;94m╭──────────────────────────────────────────────────────────────────────────────╮\x1b[0m\n"
4772
+ f"\x1b[1;94m│\x1b[0m \x1b[1;96m✦ \x1b[1mChemQL\x1b[0m \x1b[97mv{__version__}\x1b[0m \x1b[90m│\x1b[0m \x1b[1m\x1b[97mTHE PYTHON CHEMISTRY QUERY LANGUAGE\x1b[0m \x1b[1;94m│\x1b[0m\n"
4773
+ "\x1b[1;94m│\x1b[0m \x1b[90mQuery chemistry · automate calculations · build reusable programs\x1b[0m \x1b[1;94m│\x1b[0m\n"
4774
+ "\x1b[1;94m╰──────────────────────────────────────────────────────────────────────────────╯\x1b[0m\n"
4775
+ "\n"
4776
+ "\x1b[1;93m\x1b[1m▶ QUICK START\x1b[0m\n"
4777
+ " \x1b[92msearch elements ... \x1b[0m \x1b[90m│\x1b[0m Search the periodic table\n"
4778
+ " \x1b[92msearch molecules ... \x1b[0m \x1b[90m│\x1b[0m Search molecule records\n"
4779
+ " \x1b[92msearch reactions ... \x1b[0m \x1b[90m│\x1b[0m Search stored reactions\n"
4780
+ " \x1b[92mfindel \"He\" \x1b[0m \x1b[90m│\x1b[0m Find an element\n"
4781
+ " \x1b[92mfindmol \"Water\" \x1b[0m \x1b[90m│\x1b[0m Find a molecule\n"
4782
+ " \x1b[92mfindre \"Haber process\" \x1b[0m \x1b[90m│\x1b[0m Find a reaction\n"
4783
+ " \x1b[92mbalance H2 + O2 -> H2O \x1b[0m \x1b[90m│\x1b[0m Balance a chemical equation\n"
4784
+ " \x1b[92mhelp or ? \x1b[0m \x1b[90m│\x1b[0m Display this help message\n"
4785
+ " \x1b[92mversion \x1b[0m \x1b[90m│\x1b[0m Display the installed version\n"
4786
+ " \x1b[92mexit \x1b[0m \x1b[90m│\x1b[0m Exit the interactive prompt\n"
4787
+ "\n"
4788
+ "\x1b[1;93m\x1b[1m◆ CHEMICAL DATA & SEARCH\x1b[0m\n"
4789
+ " \x1b[1;96msearch elements [conditions] \x1b[0m \x1b[90m│\x1b[0m Query element data\n"
4790
+ " \x1b[1;96msearch molecules [conditions] \x1b[0m \x1b[90m│\x1b[0m Query molecule data\n"
4791
+ " \x1b[1;96msearch reactions [conditions] \x1b[0m \x1b[90m│\x1b[0m Query stored reaction data\n"
4792
+ " \x1b[1;96msource elements|molecules|reactions\x1b[0m \x1b[90m│\x1b[0m Set the current source\n"
4793
+ " \x1b[1;96mlist all \x1b[0m \x1b[90m│\x1b[0m List available fields and sources\n"
4794
+ " \x1b[95msearch elements symbol = \"Fe\" return name symbol number\x1b[0m\n"
4795
+ " \x1b[95msearch molecules molecular_weight < 50 sort molecular_weight limit 10\x1b[0m\n"
4796
+ " \x1b[95msearch reactions reversible = true return name equation source\x1b[0m\n"
4797
+ "\n"
4798
+ "\x1b[1;93m\x1b[1m◆ FILTERS & LOGIC\x1b[0m\n"
4799
+ " \x1b[1;96m= != > < >= <= \x1b[0m \x1b[90m│\x1b[0m Comparison operators\n"
4800
+ " \x1b[1;96mlike \x1b[0m \x1b[90m│\x1b[0m Case-insensitive wildcard match\n"
4801
+ " \x1b[1;96mlike! \x1b[0m \x1b[90m│\x1b[0m Case-sensitive wildcard match\n"
4802
+ " \x1b[1;96mlikep \x1b[0m \x1b[90m│\x1b[0m Pattern-based matching\n"
4803
+ " \x1b[1;96mhas \x1b[0m \x1b[90m│\x1b[0m Check whether a collection contains an item\n"
4804
+ " \x1b[1;96mand / or \x1b[0m \x1b[90m│\x1b[0m Combine conditions\n"
4805
+ " \x1b[95msearch elements number > 10 and number < 20\x1b[0m\n"
4806
+ " \x1b[95msearch molecules name like \"*water*\"\x1b[0m\n"
4807
+ " \x1b[95msearch reactions reactants has \"O2\" and products has \"H2O\"\x1b[0m\n"
4808
+ "\n"
4809
+ "\x1b[1;93m\x1b[1m◆ RESULT OPERATIONS\x1b[0m\n"
4810
+ " \x1b[92mfirst / last \x1b[0m \x1b[90m│\x1b[0m Select the first or last result\n"
4811
+ " \x1b[92msort FIELD [asc|desc] \x1b[0m \x1b[90m│\x1b[0m Sort matching records\n"
4812
+ " \x1b[92mlimit N \x1b[0m \x1b[90m│\x1b[0m Limit the number of results\n"
4813
+ " \x1b[92mcount \x1b[0m \x1b[90m│\x1b[0m Count matching records\n"
4814
+ " \x1b[92mreturn FIELD ... \x1b[0m \x1b[90m│\x1b[0m Choose fields to display\n"
4815
+ " \x1b[92munion / intersection \x1b[0m \x1b[90m│\x1b[0m Combine result sets\n"
4816
+ " \x1b[95msearch molecules molecular_weight < 20 sort molecular_weight asc limit 5\x1b[0m\n"
4817
+ "\n"
4818
+ "\x1b[1;93m\x1b[1m◆ REACTIONS & CONDITIONS\x1b[0m\n"
4819
+ " \x1b[1;96mbalance H2 + O2 -> H2O \x1b[0m \x1b[90m│\x1b[0m Balance an equation\n"
4820
+ " \x1b[1;96mbalance N2 + H2 <-> NH3 \x1b[0m \x1b[90m│\x1b[0m Balance a reversible equation\n"
4821
+ " \x1b[1;96mreact N2 3H2 \x1b[0m \x1b[90m│\x1b[0m Find a matching stored reaction\n"
4822
+ " \x1b[1;96mset temperature 150C \x1b[0m \x1b[90m│\x1b[0m Set the reaction temperature\n"
4823
+ " \x1b[1;96mset pressure 1atm \x1b[0m \x1b[90m│\x1b[0m Set the reaction pressure\n"
4824
+ " \x1b[1;96mset catalysts iron zinc \x1b[0m \x1b[90m│\x1b[0m Set available catalysts\n"
4825
+ " \x1b[1;96mset catalysts \x1b[0m \x1b[90m│\x1b[0m Clear the catalyst list\n"
4826
+ " \x1b[1;96madd catalyst \"Iron\" \x1b[0m \x1b[90m│\x1b[0m Add a catalyst\n"
4827
+ " \x1b[1;96mremove catalyst \"Iron\" \x1b[0m \x1b[90m│\x1b[0m Remove a catalyst\n"
4828
+ " \x1b[1;96mconditions \x1b[0m \x1b[90m│\x1b[0m Display current conditions\n"
4829
+ " \x1b[2mTemperature units: K, C, F. Pressure units include Pa, bar, and atm.\x1b[0m\n"
4830
+ "\n"
4831
+ "\x1b[1;93m\x1b[1m◆ VARIABLES & DEFINITIONS\x1b[0m\n"
4832
+ " \x1b[95mlet answer = 42 \x1b[0m \x1b[90m│\x1b[0m Create or assign a variable\n"
4833
+ " \x1b[95munset answer \x1b[0m \x1b[90m│\x1b[0m Remove a variable\n"
4834
+ " \x1b[95mvariables \x1b[0m \x1b[90m│\x1b[0m List current variables\n"
4835
+ " \x1b[95mdefine MAX 9 \x1b[0m \x1b[90m│\x1b[0m Define a literal replacement\n"
4836
+ " \x1b[95m@MAX \x1b[0m \x1b[90m│\x1b[0m Use a definition\n"
4837
+ " \x1b[95mdefinitions \x1b[0m \x1b[90m│\x1b[0m List definitions\n"
4838
+ " \x1b[95mremove definition MAX \x1b[0m \x1b[90m│\x1b[0m Remove a definition\n"
4839
+ " \x1b[95mdefine MAX 9\x1b[0m\n"
4840
+ " \x1b[95msearch elements number <= @MAX\x1b[0m\n"
4841
+ "\n"
4842
+ "\x1b[1;93m\x1b[1m◆ FUNCTIONS & MACROS\x1b[0m\n"
4843
+ " \x1b[95mfunc square \x1b[0m \x1b[90m│\x1b[0m Start a function definition\n"
4844
+ " \x1b[95mreturn [\\1 * \\1] \x1b[0m \x1b[90m│\x1b[0m Return a value using argument \\1\n"
4845
+ " \x1b[95mendfunc \x1b[0m \x1b[90m│\x1b[0m Finish a function definition\n"
4846
+ " \x1b[95msquare{5} \x1b[0m \x1b[90m│\x1b[0m Call a function\n"
4847
+ " \x1b[95mdefine double{} \x1b[0m \x1b[90m│\x1b[0m Start a macro definition\n"
4848
+ " \x1b[95menddefine \x1b[0m \x1b[90m│\x1b[0m Finish a macro definition\n"
4849
+ " \x1b[95m@double{5} \x1b[0m \x1b[90m│\x1b[0m Expand and execute a macro\n"
4850
+ " \x1b[95mmacros \x1b[0m \x1b[90m│\x1b[0m List defined macros\n"
4851
+ " \x1b[2mFunction and macro arguments use positional placeholders: \\1, \\2, and so on.\x1b[0m\n"
4852
+ "\n"
4853
+ "\x1b[1;93m\x1b[1m◆ CONTROL FLOW\x1b[0m\n"
4854
+ " \x1b[95mif condition ... endif \x1b[0m \x1b[90m│\x1b[0m Conditional execution\n"
4855
+ " \x1b[95mif / elif / else / endif \x1b[0m \x1b[90m│\x1b[0m Branch between conditions\n"
4856
+ " \x1b[95mfor item in iterable ... endfor\x1b[0m \x1b[90m│\x1b[0m Iterate over values\n"
4857
+ " \x1b[95mwhile condition ... endwhile \x1b[0m \x1b[90m│\x1b[0m Repeat while a condition holds\n"
4858
+ " \x1b[95mbreak / continue \x1b[0m \x1b[90m│\x1b[0m Control loop execution\n"
4859
+ " \x1b[95mfor i in range(5)\x1b[0m\n"
4860
+ " \x1b[95mlet value = i\x1b[0m\n"
4861
+ " \x1b[95mendfor\x1b[0m\n"
4862
+ " \x1b[2mPython-style blocks are also available: [for ...] ... [endblock].\x1b[0m\n"
4863
+ "\n"
4864
+ "\x1b[1;93m\x1b[1m◆ ERROR HANDLING\x1b[0m\n"
4865
+ " \x1b[95mrisk ... endrisk \x1b[0m \x1b[90m│\x1b[0m Run a protected block\n"
4866
+ " \x1b[95mfix \x1b[0m \x1b[90m│\x1b[0m Handle an error from the risk block\n"
4867
+ " \x1b[95mcleanup \x1b[0m \x1b[90m│\x1b[0m Run cleanup whether successful or not\n"
4868
+ " \x1b[95msignal \"message\" \x1b[0m \x1b[90m│\x1b[0m Raise a ChemQL signal\n"
4869
+ " \x1b[95merror \x1b[0m \x1b[90m│\x1b[0m Inspect the error type in a fix block\n"
4870
+ " \x1b[95mrisk\x1b[0m\n"
4871
+ " \x1b[95msignal \"Something went wrong\"\x1b[0m\n"
4872
+ " \x1b[95mfix\x1b[0m\n"
4873
+ " \x1b[95mlet handled = error\x1b[0m\n"
4874
+ " \x1b[95mcleanup\x1b[0m\n"
4875
+ " \x1b[95mlet finished = true\x1b[0m\n"
4876
+ " \x1b[95mendrisk\x1b[0m\n"
4877
+ " \x1b[2mThe variable error contains the error type, or None after success.\x1b[0m\n"
4878
+ "\n"
4879
+ "\x1b[1;93m\x1b[1m◆ STRUCTS & METHODS\x1b[0m\n"
4880
+ " \x1b[95mstruct Name \x1b[0m \x1b[90m│\x1b[0m Define a structured data type\n"
4881
+ " \x1b[95mrecord Name \x1b[0m \x1b[90m│\x1b[0m Define or use record data\n"
4882
+ " \x1b[95mfunc Type.__add__ \x1b[0m \x1b[90m│\x1b[0m Define an operator method\n"
4883
+ " \x1b[2mStruct methods can implement custom behaviour and operator overloads.\x1b[0m\n"
4884
+ "\n"
4885
+ "\x1b[1;93m\x1b[1m◆ PYTHON INTEGRATION\x1b[0m\n"
4886
+ " \x1b[1;96m[x = 10] \x1b[0m \x1b[90m│\x1b[0m Execute a Python statement\n"
4887
+ " \x1b[1;96m[print(x)] \x1b[0m \x1b[90m│\x1b[0m Run Python code\n"
4888
+ " \x1b[1;96m[x * 2] \x1b[0m \x1b[90m│\x1b[0m Evaluate a Python expression\n"
4889
+ " \x1b[95m{{ search elements name = \"Hydrogen\" }}\x1b[0m\n"
4890
+ " \x1b[2mEmbedded {{ ... }} queries return results as values.\x1b[0m\n"
4891
+ " Multiline Python blocks:\n"
4892
+ " \x1b[95m[[[\x1b[0m\n"
4893
+ " \x1b[95mfor x in range(3):\x1b[0m\n"
4894
+ " \x1b[95m print(x)\x1b[0m\n"
4895
+ " \x1b[95m]]]\x1b[0m\n"
4896
+ "\n"
4897
+ "\x1b[1;93m\x1b[1m◆ SHELL, COMMENTS & COMPOSITION\x1b[0m\n"
4898
+ " \x1b[1;96m`command` \x1b[0m \x1b[90m│\x1b[0m Run a system-shell command\n"
4899
+ " \x1b[1;96m```bash ... ``` \x1b[0m \x1b[90m│\x1b[0m Run a multiline shell block\n"
4900
+ " \x1b[1;96m// comment \x1b[0m \x1b[90m│\x1b[0m Single-line comment\n"
4901
+ " \x1b[1;96m/// ... /// \x1b[0m \x1b[90m│\x1b[0m Multiline comment\n"
4902
+ " \x1b[1;96mcommand1; command2 \x1b[0m \x1b[90m│\x1b[0m Execute multiple commands\n"
4903
+ " \x1b[1;96m\\ \x1b[0m \x1b[90m│\x1b[0m Continue input on the next line\n"
4904
+ " \x1b[1;96mview \x1b[0m \x1b[90m│\x1b[0m Open the periodic-table viewer\n"
4905
+ " \x1b[1;96mclear \x1b[0m \x1b[90m│\x1b[0m Clear the terminal\n"
4906
+ "\n"
4907
+ "\x1b[1;93m\x1b[1m◆ EXECUTION HISTORY\x1b[0m\n"
4908
+ " \x1b[92mdump FILE \x1b[0m \x1b[90m│\x1b[0m Export queries and results\n"
4909
+ " \x1b[92mdump all FILE \x1b[0m \x1b[90m│\x1b[0m Export all execution records\n"
4910
+ " \x1b[92mdump good FILE \x1b[0m \x1b[90m│\x1b[0m Export successful executions\n"
4911
+ " \x1b[92mdump bad FILE \x1b[0m \x1b[90m│\x1b[0m Export failed executions\n"
4912
+ " \x1b[92mdump all|good|bad queries FILE\x1b[0m \x1b[90m│\x1b[0m Export query text only\n"
4913
+ " \x1b[92mdump all|good|bad results FILE\x1b[0m \x1b[90m│\x1b[0m Export results only\n"
4914
+ "\n"
4915
+ "\x1b[1;93m\x1b[1m◆ COMMAND-LINE OPTIONS\x1b[0m\n"
4916
+ " \x1b[1;96mchemql \x1b[0m \x1b[90m│\x1b[0m Start the interactive prompt\n"
4917
+ " \x1b[1;96mchemql -c \"COMMAND\" \x1b[0m \x1b[90m│\x1b[0m Execute one command\n"
4918
+ " \x1b[1;96mchemql -f FILE \x1b[0m \x1b[90m│\x1b[0m Execute a file\n"
4919
+ " \x1b[1;96mchemql --version \x1b[0m \x1b[90m│\x1b[0m Display version information\n"
4920
+ " \x1b[1;96mchemql --no-ansi \x1b[0m \x1b[90m│\x1b[0m Disable ANSI styling\n"
4921
+ " \x1b[1;96mchemql -c \"COMMAND\" -o FILE \x1b[0m \x1b[90m│\x1b[0m Save command output to a file\n"
4922
+ " \x1b[1;96mchemql --upgrade [VERSION] \x1b[0m \x1b[90m│\x1b[0m Upgrade ChemQL\n"
4923
+ " \x1b[1;96mchemql --force \x1b[0m \x1b[90m│\x1b[0m Override package-manager protections\n"
4924
+ "\n"
4925
+ "\x1b[1;93m\x1b[1m◆ PYTHON API\x1b[0m\n"
4926
+ " \x1b[95mfrom chemql import execute_query_text, execute_query\x1b[0m\n"
4927
+ " \x1b[95mresult = execute_query_text('search elements symbol = \"O\"')\x1b[0m\n"
4928
+ " \x1b[2mDistribution: chemql-python · Import and CLI name: chemql\x1b[0m\n"
4929
+ "\n"
4930
+ "\x1b[1;93m\x1b[1m⚠ SAFETY NOTES\x1b[0m\n"
4931
+ " \x1b[2mPython blocks and shell commands execute real code with your permissions.\x1b[0m\n"
4932
+ " \x1b[2mOnly run code and commands you trust. External lookups require network access.\x1b[0m\n"
4933
+ "\n"
4934
+ "\x1b[1;94m────────────────────────────────────────────────────────────────────────────────\x1b[0m\n"
4935
+ f"\x1b[90mChemQL {__version__} · Type \x1b[92mhelp\x1b[90m for help, or \x1b[92mexit\x1b[90m to quit.\x1b[0m\n"
4936
+ )
4937
+
4770
4938
 
4771
4939
  import webbrowser
4772
4940
  from pathlib import Path
@@ -5517,7 +5685,7 @@ def run_interactive():
5517
5685
  try:
5518
5686
  print(_dump_history(first_line.strip()))
5519
5687
  except Exception as exc:
5520
- print(f"Error: {exc}")
5688
+ print(f"Error: {exc}" if NO_ANSI else "\033[31m" + f"Error: {exc}" + "\033[0m")
5521
5689
  continue
5522
5690
 
5523
5691
  if not first_line.strip():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chemql-python
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: A chemistry-focused query language and REPL
5
5
  Author-email: Mohammad Rakibul Islam <rakibulofficial1017@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -19,7 +19,7 @@ SQL-inspired syntax, inspect elements and molecules, look up reactions,
19
19
  balance equations, and combine chemistry queries with Python and shell
20
20
  commands.
21
21
 
22
- - **Version:** `1.3.0`
22
+ - **Version:** `1.3.1`
23
23
  - **PyPI distribution:** `chemql-python`
24
24
  - **Python import / CLI name:** `chemql`
25
25
  - **Author:** Mohammad Rakibul Islam
File without changes
File without changes