Repository: sqlfluff/sqlfluff

Issue:
Expose supported dialects for import
As a developer using SQLFluff in other projects, it would be helpful to have a list of supported dialects available for import.

Currently I maintain a list of dialects inferred from the project source:

```python
supported_dialects = [
    "bigquery", "mysql", "teradata", "postgres", "snowflake", "exasol", "exasol_fs"
]
```

It would be great to replace this with:

```python
from sqlfluff import SUPPORTED_DIALECTS
```

Discussion:

Patch:
diff --git a/examples/04_getting_rules_and_dialects.py b/examples/04_getting_rules_and_dialects.py
new file mode 100644
index 000000000..1ab291813
--- /dev/null
+++ b/examples/04_getting_rules_and_dialects.py
@@ -0,0 +1,18 @@
+"""This is an example of how get basic options from sqlfluff."""
+
+import sqlfluff
+
+#  -------- DIALECTS ----------
+
+dialects = sqlfluff.dialects()
+# dialects = [DialectTuple(label='ansi', name='ansi', inherits_from='nothing'), ...]
+dialect_names = [dialect.label for dialect in dialects]
+# dialect_names = ["ansi", "snowflake", ...]
+
+
+#  -------- RULES ----------
+
+rules = sqlfluff.rules()
+# rules = [RuleTuple(code='Example_L001', description='ORDER BY on these columns is forbidden!'), ...]
+rule_codes = [rule.code for rule in rules]
+# rule_codes = ["L001", "L002", ...]
diff --git a/src/sqlfluff/__init__.py b/src/sqlfluff/__init__.py
index d70d907a6..876ff74c0 100644
--- a/src/sqlfluff/__init__.py
+++ b/src/sqlfluff/__init__.py
@@ -2,7 +2,7 @@
 import sys
 
 # Expose the public API.
-from sqlfluff.api import lint, fix, parse  # noqa: F401
+from sqlfluff.api import lint, fix, parse, rules, dialects  # noqa: F401
 
 # Check major python version
 if sys.version_info[0] < 3:
diff --git a/src/sqlfluff/api/__init__.py b/src/sqlfluff/api/__init__.py
index fd17062cf..e2cc2cefc 100644
--- a/src/sqlfluff/api/__init__.py
+++ b/src/sqlfluff/api/__init__.py
@@ -4,3 +4,4 @@
 
 # Expose the simple api
 from sqlfluff.api.simple import lint, fix, parse
+from sqlfluff.api.info import rules, dialects
diff --git a/src/sqlfluff/api/info.py b/src/sqlfluff/api/info.py
new file mode 100644
index 000000000..84163c9f7
--- /dev/null
+++ b/src/sqlfluff/api/info.py
@@ -0,0 +1,18 @@
+"""Information API."""
+
+from typing import List
+
+from sqlfluff.core import dialect_readout, Linter
+from sqlfluff.core.linter import RuleTuple
+from sqlfluff.core.dialects import DialectTuple
+
+
+def rules() -> List[RuleTuple]:
+    """Return a list of available rule tuples."""
+    linter = Linter()
+    return linter.rule_tuples()
+
+
+def dialects() -> List[DialectTuple]:
+    """Return a list of available dialect info."""
+    return list(dialect_readout())
diff --git a/src/sqlfluff/cli/formatters.py b/src/sqlfluff/cli/formatters.py
index c1d02f153..3aee64952 100644
--- a/src/sqlfluff/cli/formatters.py
+++ b/src/sqlfluff/cli/formatters.py
@@ -161,8 +161,13 @@ def format_dialects(dialect_readout, verbose=0):
     text_buffer = StringIO()
     text_buffer.write("==== sqlfluff - dialects ====\n")
     readouts = [
-        (d["label"], "{name} dialect [inherits from '{inherits_from}']".format(**d))
-        for d in dialect_readout()
+        (
+            dialect.label,
+            "{dialect.name} dialect [inherits from '{dialect.inherits_from}']".format(
+                dialect=dialect
+            ),
+        )
+        for dialect in dialect_readout()
     ]
     text_buffer.write(
         cli_table(readouts, col_width=60, cols=1, label_color="blue", val_align="right")
diff --git a/src/sqlfluff/core/dialects/__init__.py b/src/sqlfluff/core/dialects/__init__.py
index d404668c3..031a84f3b 100644
--- a/src/sqlfluff/core/dialects/__init__.py
+++ b/src/sqlfluff/core/dialects/__init__.py
@@ -1,5 +1,7 @@
 """Contains SQL Dialects."""
 
+from typing import NamedTuple
+
 from sqlfluff.core.dialects.dialect_ansi import ansi_dialect
 from sqlfluff.core.dialects.dialect_bigquery import bigquery_dialect
 from sqlfluff.core.dialects.dialect_mysql import mysql_dialect
@@ -22,15 +24,23 @@ _dialect_lookup = {
 }
 
 
+class DialectTuple(NamedTuple):
+    """Dialect Tuple object for describing dialects."""
+
+    label: str
+    name: str
+    inherits_from: str
+
+
 def dialect_readout():
     """Generate a readout of available dialects."""
     for dialect_label in _dialect_lookup:
         d = _dialect_lookup[dialect_label]
-        yield {
-            "label": dialect_label,
-            "name": d.name,
-            "inherits_from": d.inherits_from or "nothing",
-        }
+        yield DialectTuple(
+            label=dialect_label,
+            name=d.name,
+            inherits_from=d.inherits_from or "nothing",
+        )
 
 
 def dialect_selector(s):
diff --git a/src/sqlfluff/core/linter.py b/src/sqlfluff/core/linter.py
index 90fb9a773..0dacdd0da 100644
--- a/src/sqlfluff/core/linter.py
+++ b/src/sqlfluff/core/linter.py
@@ -46,6 +46,13 @@ from sqlfluff.core.rules.base import BaseCrawler
 linter_logger: logging.Logger = logging.getLogger("sqlfluff.linter")
 
 
+class RuleTuple(NamedTuple):
+    """Rule Tuple object for describing rules."""
+
+    code: str
+    description: str
+
+
 class ProtoFile(NamedTuple):
     """Proto object to be inherited by LintedFile."""
 
@@ -732,10 +739,10 @@ class Linter:
         cfg = config or self.config
         return rs.get_rulelist(config=cfg)
 
-    def rule_tuples(self) -> List[Tuple[str, str]]:
+    def rule_tuples(self) -> List[RuleTuple]:
         """A simple pass through to access the rule tuples of the rule set."""
         rs = self.get_ruleset()
-        return [(rule.code, rule.description) for rule in rs]
+        return [RuleTuple(rule.code, rule.description) for rule in rs]
 
     def parse_string(
         self,


Test patch:
diff --git a/test/api/info_test.py b/test/api/info_test.py
new file mode 100644
index 000000000..379623d39
--- /dev/null
+++ b/test/api/info_test.py
@@ -0,0 +1,17 @@
+"""Test using sqlfluff to extract elements of queries."""
+
+import sqlfluff
+
+
+def test__api__info_dialects():
+    """Basic linting of dialects."""
+    dialects = sqlfluff.dialects()
+    assert isinstance(dialects, list)
+    assert ("ansi", "ansi", "nothing") in dialects
+
+
+def test__api__info_rules():
+    """Basic linting of dialects."""
+    rules = sqlfluff.rules()
+    assert isinstance(rules, list)
+    assert ("L001", "Unnecessary trailing whitespace.") in rules