Repository: streamlit/streamlit

Issue:
st.json collapse parameter
_(Note, you don't have to fill out every section here. They're just here for guidance. That said, nicely detailed feature requests are more likely to get eng attention sooner)_

### Problem

Have a parameter for st.json(body, collapse) where the default is `False` but you can set it to `True`. This would allow developers to choose if the json file is expanded or collapsed when rendered on the Streamlit app.

Requested by a community member, link to forum post: 
https://discuss.streamlit.io/t/json-collapse-option/17159

### Solution

**MVP:** a parameter to set the view of a json file on the first render in Streamlit




Discussion:
By default st.json(body) displays a js widget for dictionaries that is fully expanded. That's fine for small documents but large dictionaries/json docs can make is unwildly for users to read through and identify important keys.

Suggestion is to:

Make the streamlit.json() function accept a collapse=True argument to collapse values that are objects under root level keys.

For example:

Show
`
{
“names” : [“Amber”, “Simone”, “Paul”]
}
`
As
`
{
“names”: […]
}
`

When `streamlit.json(body, collapse=True)`

Thank you.
Endorse this idea, it is good and I need this right now for my production application.

  For extra credit, allow the parameter to specify specific keys for expansion or collapsed.
Hi,

I want to volunteer to fix this issue. Let me know it it's okay.

Thanks,
Archil

@vdonato 
Hi @archilk, thanks for volunteering -- feel free to give this issue a try!
@vdonato Awesome, will attempt it in the coming weekend. I'm a newbie though so please bear with me.
Any news on this?
> Any news on this?

Hey, I haven't got a chance to work on this, some unexpected circumstances got in the way. If someone else wants to pick it up earlier, please feel free, as January seems very packed for me too
@vdonato wondering where is this on roadmap? Thx!
Thanks for bumping this issue, @john-mercer-allstripes!

I don't believe it's currently on the roadmap, and I haven't been watching this issue too closely myself.

However, it seems like there's a good amount of interest for it, and I think it should be a pretty easy feature to add (I'm guessing it'll just be a few tens of lines of code), so I'll see if we can prioritize it in the next few weeks. I don't think I'll have much bandwidth until close to the end of this month, though, so it's unlikely I'll be able to pick this up until then.

(CC @jrieke)
Given the amount of json data that's out there, this feature seems like it will have a lot of leverage.

Resolving patch:
diff --git a/e2e/scripts/st_json.py b/e2e/scripts/st_json.py
--- a/e2e/scripts/st_json.py
+++ b/e2e/scripts/st_json.py
@@ -16,3 +16,4 @@
 
 data = {"foo": "bar"}
 st.json(data)
+st.json(data, expanded=False)
diff --git a/lib/streamlit/elements/json.py b/lib/streamlit/elements/json.py
--- a/lib/streamlit/elements/json.py
+++ b/lib/streamlit/elements/json.py
@@ -21,7 +21,12 @@
 
 
 class JsonMixin:
-    def json(self, body):
+    def json(
+        self,
+        body,
+        *,  # keyword-only arguments:
+        expanded=True,
+    ):
         """Display object or string as a pretty-printed JSON string.
 
         Parameters
@@ -31,6 +36,11 @@ def json(self, body):
             serializable to JSON as well. If object is a string, we assume it
             contains serialized JSON.
 
+        expanded : bool
+            An optional boolean that allows the user to set whether the initial
+            state of this json element should be expanded. Defaults to True.
+            This argument can only be supplied by keyword.
+
         Example
         -------
         >>> st.json({
@@ -66,6 +76,7 @@ def json(self, body):
 
         json_proto = JsonProto()
         json_proto.body = body
+        json_proto.expanded = expanded
         return self.dg._enqueue("json", json_proto)
 
     @property


Test patch:
diff --git a/lib/tests/streamlit/delta_generator_test.py b/lib/tests/streamlit/delta_generator_test.py
--- a/lib/tests/streamlit/delta_generator_test.py
+++ b/lib/tests/streamlit/delta_generator_test.py
@@ -377,6 +377,7 @@ def test_json_object(self):
 
         element = self.get_delta_from_queue().new_element
         self.assertEqual(json_string, element.json.body)
+        self.assertEqual(True, element.json.expanded)
 
     def test_json_string(self):
         """Test Text.JSON string."""
@@ -400,6 +401,19 @@ def test_json_unserializable(self):
         # validate a substring since repr for a module may contain an installation-specific path
         self.assertTrue(element.json.body.startswith("\"<module 'json'"))
 
+    def test_json_not_expanded_arg(self):
+        """Test st.json expanded arg."""
+        json_data = {"key": "value"}
+
+        # Testing python object
+        st.json(json_data, expanded=False)
+
+        json_string = json.dumps(json_data)
+
+        element = self.get_delta_from_queue().new_element
+        self.assertEqual(json_string, element.json.body)
+        self.assertEqual(False, element.json.expanded)
+
     def test_markdown(self):
         """Test Markdown element."""
         test_string = "    data         "