Repository: cogent3/cogent3 (language: python)

Issue:
cookbook for apps
Apps need documentation!! This should be structured based on the type of apps, i.e., loaders, filtering steps, data sampling apps. 

- reorganise the current app documentation

### todo: cookbook
- [x] io
- [ ] dist
- [ ] tree 
- [ ] align
- [ ] evo 
- [ ] translate 
- [x] sample 

### todo: docstrings
- [ ] io
- [ ] dist
- [ ] tree 
- [ ] align
- [ ] evo 
- [x] translate 
- [x] sample 



Discussion / hints:
related to #1378 
Following up on how to include code snippets, here is the [numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html#examples) description of how they should be formatted.
Running `pytest` catches the code snippets in a simple example by adding:

- The code snippet in the docstring, with a pass and fail conditions
https://github.com/fredjaya/DemoProject/blob/ea776bc185b1cd252068619e2f0862a0d34b7c78/src/myproject/cli.py#L94-L101

- doctest options in the .toml
https://github.com/fredjaya/DemoProject/blob/ea776bc185b1cd252068619e2f0862a0d34b7c78/pyproject.toml?plain=1#L53-L55

Output is:
```
================ test session starts =================
platform linux -- Python 3.11.6, pytest-7.4.3, pluggy-1.3.0
rootdir: /home/frederickjaya/GitHub/DemoProject
configfile: pyproject.toml
testpaths: tests, src/myproject
plugins: anyio-4.1.0, cov-4.1.0, xdist-3.5.0
collected 3 items                                    

tests/test_myproject.py ..                     [ 66%]
src/myproject/cli.py F                         [100%]

====================== FAILURES ======================
_______ [doctest] myproject.cli._parse_csv_arg _______
095 
096     >>> _parse_csv_arg("test")
097     ['test']
098     >>> _parse_csv_arg("test")
Expected:
    ['fail']
Got:
    ['test']

/home/frederickjaya/mambaforge/envs/c311/lib/python3.11/site-packages/myproject/cli.py:98: DocTestFailure
============== short test summary info ===============
FAILED src/myproject/cli.py::myproject.cli._parse_csv_arg

```
Thanks @fredjaya ! I'm going to create another issue to trial this for one of the apps.

Fix patch:
diff --git a/pyproject.toml b/pyproject.toml
index 0f1a9f0d0..a8a8f3ced 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -176,12 +176,8 @@ new_fragment_template="file: changelog.d/templates/new.md.j2"
 entry_title_template="file: changelog.d/templates/title.md.j2"
 
 [project.entry-points."cogent3.app"]
-compress = "cogent3.app.io:compress"
 concat = "cogent3.app.sample:concat"
-decompress = "cogent3.app.io:decompress"
 fixed_length = "cogent3.app.sample:fixed_length"
-from_json = "cogent3.app.io:from_json"
-from_primitive = "cogent3.app.io:from_primitive"
 load_aligned = "cogent3.app.io:load_aligned"
 load_db = "cogent3.app.io:load_db"
 load_json = "cogent3.app.io:load_json"
@@ -192,16 +188,12 @@ omit_bad_seqs = "cogent3.app.sample:omit_bad_seqs"
 omit_degenerates = "cogent3.app.sample:omit_degenerates"
 omit_duplicated = "cogent3.app.sample:omit_duplicated"
 omit_gap_pos = "cogent3.app.sample:omit_gap_pos"
-pickle_it = "cogent3.app.io:pickle_it"
 select_translatable = "cogent3.app.translate:select_translatable"
 take_codon_positions = "cogent3.app.sample:take_codon_positions"
 take_n_seqs = "cogent3.app.sample:take_n_seqs"
 take_named_seqs = "cogent3.app.sample:take_named_seqs"
-to_json = "cogent3.app.io:to_json"
-to_primitive = "cogent3.app.io:to_primitive"
 translate_seqs = "cogent3.app.translate:translate_seqs"
 trim_stop_codons = "cogent3.app.sample:trim_stop_codons"
-unpickle_it = "cogent3.app.io:unpickle_it"
 write_db = "cogent3.app.io:write_db"
 write_json = "cogent3.app.io:write_json"
 write_seqs = "cogent3.app.io:write_seqs"


Test patch:
diff --git a/tests/test_app/test_init.py b/tests/test_app/test_init.py
index 1bc91f18d..58e788295 100644
--- a/tests/test_app/test_init.py
+++ b/tests/test_app/test_init.py
@@ -133,10 +133,10 @@ def test_get_app_kwargs():
 
 
 def test_app_help(capsys):
-    app_help("compress")
+    app_help("concat")
     got = capsys.readouterr().out
     assert "Options" in got
-    assert got.count("bytes") >= 2  # both input and output types are bytes
+    assert got.count("SerialisableType") == 1  # output type
 
 
 @pytest.mark.parametrize(
diff --git a/tests/test_app/test_io.py b/tests/test_app/test_io.py
index 547c66903..8e55b1994 100644
--- a/tests/test_app/test_io.py
+++ b/tests/test_app/test_io.py
@@ -608,19 +608,19 @@ def test_default_serialiser_deserialiser(data):
 
 
 def test_to_json():
-    to_j = get_app("to_json")
+    to_j = io_app.to_json()
     data = {"a": [0, 1]}
     assert to_j(data) == json.dumps(data)
 
 
 def test_from_json():
-    from_j = get_app("from_json")
+    from_j = io_app.from_json()
     assert from_j('{"a": [0, 1]}') == {"a": [0, 1]}
 
 
 def test_to_from_json():
-    to_j = get_app("to_json")
-    from_j = get_app("from_json")
+    to_j = io_app.to_json()
+    from_j = io_app.from_json()
     app = to_j + from_j
     data = {"a": [0, 1]}
     assert app(data) == data
@@ -628,7 +628,7 @@ def test_to_from_json():
 
 
 def test_to_json_combines():
-    app = get_app("to_primitive") + get_app("to_json")
+    app = io_app.to_primitive() + io_app.to_json()
     assert app(DNA) == DNA.to_json()