parameters: (request, title)
docstring: API for retrieving a shape document for a given text or category.
      For simple texts, returns a dict with keys:
  	{
  		"section": Category immediately above book
  		"heTitle": Hebrew title of node
  		"length": Number of chapters
  		"chapters": List of Chapter Lengths (think about depth 1 & 3)
  		"title": English title of node
  		"book": English title of Book
  	}
      For complex texts or categories, returns a list of dicts.
      :param title: A valid node title or a path to a category, separated by /.
      The "depth" parameter in the query string indicates how many levels in the category tree to descend.  Default is 2.
      If depth == 0, descends to end of tree
      The "dependents" parameter, if true, includes dependent texts.  By default, they are filtered out.
docstring_summary: API for retrieving a shape document for a given text or category.
      For simple texts, returns a dict with keys:
  	{
  		"section": Category immediately above book
  		"heTitle": Hebrew title of node
  		"length": Number of chapters
  		"chapters": List of Chapter Lengths (think about depth 1 & 3)
  		"title": English title of node
  		"book": English title of Book
  	}
      For complex texts or categories, returns a list of dicts.
      :param title: A valid node title or a path to a category, separated by /.
      The "depth" parameter in the query string indicates how many levels in the category tree to descend.  Default is 2.
      If depth == 0, descends to end of tree
      The "dependents" parameter, if true, includes dependent texts.  By default, they are filtered out.
docstring_tokens: API for retrieving a shape document for a given text or category . For simple texts returns a dict with keys : { section : Category immediately above book heTitle : Hebrew title of node length : Number of chapters chapters : List of Chapter Lengths ( think about depth 1 & 3 ) title : English title of node book : English title of Book } For complex texts or categories returns a list of dicts . : param title : A valid node title or a path to a category separated by / . The depth parameter in the query string indicates how many levels in the category tree to descend . Default is 2 . If depth == 0 descends to end of tree The dependents parameter if true includes dependent texts . By default they are filtered out .
function: def shape_api(request, title):
      """
      API for retrieving a shape document for a given text or category.
      For simple texts, returns a dict with keys:
  	{
  		"section": Category immediately above book
  		"heTitle": Hebrew title of node
  		"length": Number of chapters
  		"chapters": List of Chapter Lengths (think about depth 1 & 3)
  		"title": English title of node
  		"book": English title of Book
  	}
      For complex texts or categories, returns a list of dicts.
      :param title: A valid node title or a path to a category, separated by /.
      The "depth" parameter in the query string indicates how many levels in the category tree to descend.  Default is 2.
      If depth == 0, descends to end of tree
      The "dependents" parameter, if true, includes dependent texts.  By default, they are filtered out.
      """
      from sefaria.model.category import TocCollectionNode
  
      def _simple_shape(snode):
          sn = StateNode(snode=snode)
          shape = sn.var("all", "shape")
  
          return {
              "section": snode.index.categories[-1],
              "heTitle": snode.full_title("he"),
              "title": snode.full_title("en"),
              "length": len(shape) if isinstance(shape, list) else 1,  # hmmmm
              "chapters": shape,
              "book": snode.index.title,
              "heBook": snode.index.get_title(lang="he"),
          }
  
      def _collapse_book_leaf_shapes(leaf_shapes):
          """Groups leaf node shapes for a single book into one object so that resulting list corresponds 1:1 to books"""
          if type(leaf_shapes) != list:
              return leaf_shapes
  
          results = []
          prev_shape = None
          complex_book_in_progress = None
  
          for shape in leaf_shapes:
              if prev_shape and prev_shape["book"] != shape["book"]:
                  if complex_book_in_progress:
                      results.append(complex_book_in_progress)
                      complex_book_in_progress = None
                  else:
                      results.append(prev_shape)
              elif prev_shape:
                  complex_book_in_progress = complex_book_in_progress or {
                      "isComplex": True,
                      "section": prev_shape["section"],
                      "length": prev_shape["length"],
                      "chapters": [prev_shape],
                      "book": prev_shape["book"],
                      "heBook": prev_shape["heBook"],
                  }
                  complex_book_in_progress["chapters"].append(shape)
                  complex_book_in_progress["length"] += shape["length"]
              prev_shape = shape
  
          results.append(complex_book_in_progress or prev_shape)
  
          return results
  
      title = title.replace("_", " ")
  
      if request.method == "GET":
          sn = library.get_schema_node(title, "en")
  
          # Leaf Node
          if sn and not sn.children:
              res = [_simple_shape(sn)]
  
          # Branch Node
          elif sn and sn.children:
              res = [_simple_shape(n) for n in sn.get_leaf_nodes()]
  
          # Category
          else:
              cat = library.get_toc_tree().lookup(title.split("/"))
  
              if not cat:
                  res = {"error": "No index or category found to match {}".format(title)}
              else:
                  depth = request.GET.get("depth", 2)
                  include_dependents = request.GET.get("dependents", False)
  
                  leaves = cat.get_leaf_nodes() if depth == 0 else [n for n in cat.get_leaf_nodes_to_depth(depth)]
                  leaves = [n for n in leaves if not isinstance(n, TocCollectionNode)]
                  if not include_dependents:
                      leaves = [n for n in leaves if not getattr(n, "dependence", None)]
  
                  res = [_simple_shape(jan) for toc_index in leaves for jan in toc_index.get_index_object().nodes.get_leaf_nodes()]
  
          res = _collapse_book_leaf_shapes(res)
          return jsonResponse(res, callback=request.GET.get("callback", None))
function_tokens: def shape_api ( request , title ) : from sefaria . model . category import TocCollectionNode def _simple_shape ( snode ) : sn = StateNode ( snode = snode ) shape = sn . var ( "all" , "shape" ) return { "section" : snode . index . categories [ - 1 ] , "heTitle" : snode . full_title ( "he" ) , "title" : snode . full_title ( "en" ) , "length" : len ( shape ) if isinstance ( shape , list ) else 1 , # hmmmm "chapters" : shape , "book" : snode . index . title , "heBook" : snode . index . get_title ( lang = "he" ) , } def _collapse_book_leaf_shapes ( leaf_shapes ) : """Groups leaf node shapes for a single book into one object so that resulting list corresponds 1:1 to books""" if type ( leaf_shapes ) != list : return leaf_shapes results = [ ] prev_shape = None complex_book_in_progress = None for shape in leaf_shapes : if prev_shape and prev_shape [ "book" ] != shape [ "book" ] : if complex_book_in_progress : results . append ( complex_book_in_progress ) complex_book_in_progress = None else : results . append ( prev_shape ) elif prev_shape : complex_book_in_progress = complex_book_in_progress or { "isComplex" : True , "section" : prev_shape [ "section" ] , "length" : prev_shape [ "length" ] , "chapters" : [ prev_shape ] , "book" : prev_shape [ "book" ] , "heBook" : prev_shape [ "heBook" ] , } complex_book_in_progress [ "chapters" ] . append ( shape ) complex_book_in_progress [ "length" ] += shape [ "length" ] prev_shape = shape results . append ( complex_book_in_progress or prev_shape ) return results title = title . replace ( "_" , " " ) if request . method == "GET" : sn = library . get_schema_node ( title , "en" ) # Leaf Node if sn and not sn . children : res = [ _simple_shape ( sn ) ] # Branch Node elif sn and sn . children : res = [ _simple_shape ( n ) for n in sn . get_leaf_nodes ( ) ] # Category else : cat = library . get_toc_tree ( ) . lookup ( title . split ( "/" ) ) if not cat : res = { "error" : "No index or category found to match {}" . format ( title ) } else : depth = request . GET . get ( "depth" , 2 ) include_dependents = request . GET . get ( "dependents" , False ) leaves = cat . get_leaf_nodes ( ) if depth == 0 else [ n for n in cat . get_leaf_nodes_to_depth ( depth ) ] leaves = [ n for n in leaves if not isinstance ( n , TocCollectionNode ) ] if not include_dependents : leaves = [ n for n in leaves if not getattr ( n , "dependence" , None ) ] res = [ _simple_shape ( jan ) for toc_index in leaves for jan in toc_index . get_index_object ( ) . nodes . get_leaf_nodes ( ) ] res = _collapse_book_leaf_shapes ( res ) return jsonResponse ( res , callback = request . GET . get ( "callback" , None ) )