Repository: pepkit/peppy

Issue:
Make PEP representations consistent
We currently have 3 ways of representing PEPs:

1. Schema representations -> see: https://schema.databio.org/?namespace=pep&schema=2.1.0
2. peppy.Project object -> this is a mutable mapping containing `_config` and `samples` attributes.
3. dict via peppy.Project.to_dict() -> this contains all attributes under the original `_config` key (but not the _config key!) and the `samples`.

We would like to ensure that number 3 resembles number 2, so that the data structures have both `config` and `samples` attributes. 

Finally, in this same process we have decided to rename the `config` key to `project`.

In summary:
- [ ] ensure `to_dict()`'s representation matches the peppy.Project representation
- [ ] change `config` key to `project`
- [ ] refactor `_samples` to `samples`

Discussion:

Solution patch:
diff --git a/peppy/_version.py b/peppy/_version.py
index d6d6823d..6e2b9eaa 100644
--- a/peppy/_version.py
+++ b/peppy/_version.py
@@ -1 +1 @@
-__version__ = "0.40.5"
+__version__ = "0.40.6"
diff --git a/peppy/project.py b/peppy/project.py
index 9f46cccc..b7b58e0b 100644
--- a/peppy/project.py
+++ b/peppy/project.py
@@ -345,8 +345,10 @@ def to_dict(
                 SUBSAMPLE_RAW_LIST_KEY: sub_df,
             }
         else:
-            p_dict = self.config.copy()
-            p_dict["_samples"] = [s.to_dict() for s in self.samples]
+            p_dict = {
+                "project": self.config.copy(),
+                "samples": [s.to_dict() for s in self.samples],
+            }
 
         return p_dict
 


Test patch:
diff --git a/tests/test_Project.py b/tests/test_Project.py
index 7f7a9bb9..6d573f2b 100644
--- a/tests/test_Project.py
+++ b/tests/test_Project.py
@@ -375,7 +375,7 @@ def test_to_dict_does_not_create_nans(self, example_pep_nextflow_csv_path):
         p1 = Project(
             cfg=example_pep_nextflow_csv_path, sample_table_index="sample"
         ).to_dict()
-        for sample in p1.get("_samples"):
+        for sample in p1.get("samples"):
             for attribute, value in sample.items():
                 assert value not in wrong_values