Skip to content

Commit

Permalink
feat: add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski committed Oct 10, 2024
1 parent 8d6138a commit 96f0118
Show file tree
Hide file tree
Showing 14 changed files with 1,181 additions and 182 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Docs

on:
push:
tags:
- "v*"
workflow_dispatch:

permissions:
contents: write
pages: write

jobs:
docs:
runs-on: ubuntu-latest
env:
GIT_COMMITTER_NAME: ci-bot
GIT_COMMITTER_EMAIL: [email protected]
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Install Python
run: uv python install # we use uv instead of setup-python so we get python-version resolution between our two packages
- name: Sync
run: uv sync
- name: Deploy
run: |
VERSION=$(git describe --tags --match="v*" --abbrev=0)
uv run mike deploy $VERSION latest --update-aliases --push
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
target/
debug/
**/*.rs.bk
.cache
site/
66 changes: 66 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# CLI

**cql2-rs** includes a command-line interface (CLI).

## Installation

Install [Rust](https://rustup.rs/).
Then:

```shell
cargo install cql2-cli
```

## Usage

At its simplest, the CLI is a pass-through validator:

```shell
$ cql2 < tests/fixtures/text/example01.txt # will succeed if the CQL2 is valid
("landsat:scene_id" = 'LC82030282019133LGN00')
```

You can convert formats:

```shell
$ cql2 -o json < tests/fixtures/text/example01.txt
{"op":"=","args":[{"property":"landsat:scene_id"},"LC82030282019133LGN00"]}
```

Use `-v` to get detailed validation information:

```shell
$ cql2 'wrong' -v
[ERROR] Invalid CQL2: wrong
For more detailed validation information, use -vv
jsonschema validation failed with file:///tmp/cql2.json#
- at '': oneOf failed, none matched
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': oneOf failed, none matched
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': missing properties 'op', 'args'
- at '': want boolean, but got object
```

cql2-text parsing errors are pretty-printed:

```shell
$ cql2 '(foo ~= "bar")'
[ERROR] Parsing error: (foo ~= "bar")
--> 1:6
|
1 | (foo ~= "bar")
| ^---
|
= expected NotFlag, And, Or, ConcatInfixOp, Add, Subtract, Multiply, Divide, Modulo, Power, Eq, Gt, GtEq, Lt, LtEq, NotEq, Is, or IsNullPostfix
```

Use `cql2 --help` to get a complete listing of the CLI arguments and formats.
17 changes: 17 additions & 0 deletions docs/ds-logo-hor--pos.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# cql2-rs

**cql2-rs** is [Python package](./python.md), [command-line interface (CLI)](./cli.md), and [Rust crate](./rust.md) for parsing, validating, and converting [Common Query Language (CQL2)](https://www.ogc.org/standard/cql2/).

## Python

```python
>>> from cql2 import Expr
>>> expr = Expr("landsat:scene_id = 'LC82030282019133LGN00'")
>>> expr.to_json()
{'op': '=', 'args': [{'property': 'landsat:scene_id'}, 'LC82030282019133LGN00']}
```

## CLI

```shell
$ cql2 < tests/fixtures/text/example01.txt # will succeed if the CQL2 is valid
("landsat:scene_id" = 'LC82030282019133LGN00')
```

## Rust

```rust
use cql2::Expr;
let expr: Expr = "landsat:scene_id = 'LC82030282019133LGN00'".parse();
let json = expr.to_json().unwrap();
```
13 changes: 13 additions & 0 deletions docs/python.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Python

Python API documentation for the **cql2** package.
Install from PyPI:

```shell
python -m pip install cql2
```

## API

::: cql2.Expr
::: cql2.SqlQuery
3 changes: 3 additions & 0 deletions docs/rust.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Rust

The API documentation for the **cql2** Rust library is hosted at [docs.rs](https://docs.rs/cql2).
65 changes: 65 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
site_name: cql2-rs
site_url: https://developmentseed.org/cql2-rs/
site_description: Command-line interface (CLI), Python package, and Rust crate for parsing, validating, and converting Common Query Language (CQL2)
site_author: David Bitner
repo_name: developmentseed/cql2-rs
repo_url: https://github.com/developmentseed/cql2-rs
edit_uri: edit/main/docs/

extra:
social:
- icon: "fontawesome/brands/github"
version:
provider: mike

theme:
name: material
logo: ds-logo-hor--pos.svg
favicon: favicon.png
icon:
repo: fontawesome/brands/github
palette:
primary: blue
features:
- content.action.edit
- navigation.indexes
- navigation.instant
- navigation.tabs
- navigation.tracking
- search.share
- search.suggest
- toc.integrate
nav:
- cql2-rs: index.md
- Python: python.md
- CLI: cli.md
- Rust: rust.md
plugins:
- search
- social
- mike:
alias_type: "copy"
canonical_version: "latest"
- mkdocstrings:
enable_inventory: true
handlers:
python:
options:
allow_inspection: false
show_root_heading: true
separate_signature: false
docstring_style: google
docstring_section_style: list
show_symbol_type_toc: true
signature_crossrefs: true
merge_init_into_class: true
docstring_options:
ignore_init_summary: false
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
18 changes: 18 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[project]
name = "cql2-rs"
version = "0.0.0"
description = "This Python package is non-releaseable and is only used for building the documentation"
requires-python = ">=3.12"

[tool.uv]
dev-dependencies = [
"mike>=2.1.3",
"mkdocs-material[imaging]>=9.5.39",
"mkdocstrings[python]>=0.26.1",
]

[tool.uv.sources]
python = { workspace = true }

[tool.uv.workspace]
members = ["python/"]
79 changes: 74 additions & 5 deletions python/cql2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,82 @@ from typing import Any
from os import PathLike

class SqlQuery:
"""A SQL query"""

query: str
"""The query, with parameterized fields."""

params: list[str]
"""The parameters, to use for binding."""

class Expr:
@staticmethod
def from_path(path: PathLike) -> Expr: ...
def __init__(self, cql2: str | dict[str, Any]) -> None: ...
def to_json(self) -> dict[str, Any]: ...
def to_text(self) -> str: ...
def to_sql(self) -> SqlQuery: ...
def from_path(path: PathLike) -> Expr:
"""Reads CQL2 from a filesystem path.
Args:
path (PathLike): The input path
Returns:
Expr: The CQL2 expression
Examples:
>>> from cql2 import Expr
>>> expr = Expr.from_path("fixtures/text/example01.txt")
"""

def __init__(self, cql2: str | dict[str, Any]) -> None:
"""A CQL2 expression.
The cql2 can either be a cql2-text string, a cql2-json string, or a
cql2-json dictionary.
Args:
cql2 (str | dict[str, Any]): The input CQL2
Examples:
>>> from cql2 import Expr
>>> expr = Expr("landsat:scene_id = 'LC82030282019133LGN00'")
>>> expr = Expr({"op":"=","args":[{"property":"landsat:scene_id"},"LC82030282019133LGN00"]})
"""

def to_json(self) -> dict[str, Any]:
"""Converts this cql2 expression to a cql2-json dictionary.
Returns:
dict[str, Any]: The cql2-json
Examples:
>>> from cql2 import Expr
>>> expr = Expr("landsat:scene_id = 'LC82030282019133LGN00'")
>>> expr.to_json()
{'op': '=', 'args': [{'property': 'landsat:scene_id'}, 'LC82030282019133LGN00']}
"""

def to_text(self) -> str:
"""Converts this cql2 expression to cql2-text.
Returns:
str: The cql2-text
Examples:
>>> from cql2 import Expr
>>> expr = Expr({"op":"=","args":[{"property":"landsat:scene_id"},"LC82030282019133LGN00"]})
>>> expr.to_text()
'("landsat:scene_id" = \'LC82030282019133LGN00\')'
"""

def to_sql(self) -> SqlQuery:
"""Converts this cql2 expression to a SQL query.
Returns:
SqlQuery: The SQL query and parameters
Examples:
>>> from cql2 import Expr
>>> expr = Expr("landsat:scene_id = 'LC82030282019133LGN00'")
>>> q.query
'("landsat:scene_id" = $1)'
>>> q.params
['LC82030282019133LGN00']
"""
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ classifiers = [
dynamic = ["version"]

[tool.uv]
dev-dependencies = ["mypy", "pytest", "ruff"]
dev-dependencies = ["mypy>=1.11.2", "pytest>=8.3.3", "ruff>=0.6.9"]
Loading

0 comments on commit 96f0118

Please sign in to comment.