Dvar Torah Outliner

A basic tutorial for beginners looking to get their feet wet with the Sefaria API.

Dvar Torah Outliner

Let's say you are frequently asked to prepare Divrei Torah on the Parasha (a short discourse on the weekly Torah portion), and have decided you want to use the Sefaria API to write code to help you automate an outline each week, containing the first verse of that week's Parasha along with a sampling of commentaries.

Tutorial Set Up

For this tutorial, we'll be using Python 3.8.

Make sure you have Python requests installed and imported at the top of your file:

import requests

The work we're doing in this tutorial is language agnostic, so feel free to adapt the code to follow along in any language of your choosing.

Retrieve the Parasha

Our first step is to use the Calendars API to retrieve the weekly Parasha. We'll hit the endpoint here without any customizations. If you look at the documentation for this endpoint, you'll see that it is highly customizable based on tradition, location, and cycles of readings. For the sake of this example, we'll stick with the basics.

url = "https://www.sefaria.org/api/calendars"

# Make a GET request to the URL
response = requests.get(url)

# Parse the response as JSON
data = response.json()  

If you print the value of data, you'll see a dictionary with lots of information about that day's learning schedules (i.e. Daf Yomi, Daily Rambam... and weekly Parasha).

{
  "date": "2024-02-06",
  "timezone": "America/Halifax",
  "calendar_items": [
    {
      "title": 
      {
        "en": "Parashat Hashavua",
        "he": "Χ€Χ¨Χ©Χͺ Χ”Χ©Χ‘Χ•Χ’"
      },
      "displayValue": {
        "en": "Mishpatim",
        "he": "ΧžΧ©Χ€Χ˜Χ™Χ"
      },
      "url": "Exodus.21.1-24.18",
      "ref": "Exodus 21:1-24:18",
      "heRef": "Χ©ΧžΧ•Χͺ כ״א:א׳-Χ›Χ΄Χ“:Χ™Χ΄Χ—",
      "order": 1,
      "category": "Tanakh",
      "extraDetails": {
        "aliyot": [
          "Exodus 21:1-21:19",
          "Exodus 21:20-22:3",
          "Exodus 22:4-22:26",
          "Exodus 22:27-23:5",
          "Exodus 23:6-23:19",
          "Exodus 23:20-23:25",
          "Exodus 23:26-24:18",
          "Numbers 28:9-28:15"
        ]
      },
      "description": {
        "en": "Mishpatim (β€œLaws”) recounts a series of God’s laws that Moses gives to the Israelites. These include laws about treatment of slaves, damages, loans, returning lost property, the Sabbath, the sabbatical year, holidays, and destroying idolatry. The portion ends as Moses ascends Mount Sinai for 40 days.",
        "he": "Χ€Χ¨Χ©Χͺ ΧžΧ©Χ€Χ˜Χ™Χ Χ›Χ•ΧœΧœΧͺ מב׀ר Χ’Χ“Χ•Χœ של דינים Χ•ΧžΧ¦Χ•Χ•Χͺ Χ©ΧΧœΧ•Χ”Χ™Χ ΧžΧ¦Χ•Χ•Χ” אΧͺ Χ‘Χ Χ™ Χ™Χ©Χ¨ΧΧœ Χ‘ΧΧžΧ¦Χ’Χ•Χͺ ΧžΧ©Χ”. הדינים גובקים Χ‘ΧͺΧ—Χ•ΧžΧ™Χ רבים, Χ›Χ’Χ•ΧŸ Χ’Χ‘Χ“Χ•Χͺ, Χ Χ–Χ™Χ§Χ™ΧŸ, Χ”Χ©Χ‘Χͺ אבדה, Χ©Χ‘Χͺ, Χ©ΧžΧ™Χ˜Χ”, חגים, איבור Χ’Χ‘Χ•Χ“Χ” Χ–Χ¨Χ” Χ•Χ’Χ•Χ“. Χ‘Χ‘Χ•Χ£ Χ”Χ€Χ¨Χ©Χ” מΧͺוארים ΧžΧ’ΧžΧ“ Χ›Χ¨Χ™ΧͺΧͺ Χ”Χ‘Χ¨Χ™Χͺ Χ‘Χ™ΧŸ ΧΧœΧ•Χ”Χ™Χ לגם Χ•Χ’ΧœΧ™Χ™Χͺ ΧžΧ©Χ” ΧœΧ”Χ¨ Χ‘Χ™Χ Χ™ ל40 יום Χ•40 ΧœΧ™ΧœΧ”."
      }
    },
    {
      "title": {
          "en": "Haftarah",
          "he": "Χ”Χ€Χ˜Χ¨Χ”"
      },
      "displayValue": {
          "en": "Isaiah 66:1-24",
          "he": "Χ™Χ©Χ’Χ™Χ”Χ• Χ‘Χ΄Χ•:א׳-Χ›Χ΄Χ“"
      },
      "url": "Isaiah.66.1-24",
      "ref": "Isaiah 66:1-24",
      "order": 2,
      "category": "Tanakh"
      },
      {
      "title": {
          "en": "Daf Yomi",
          "he": "Χ“Χ£ Χ™Χ•ΧžΧ™"
      },
      "displayValue": {
          "en": "Bava Kamma 96",
          "he": "בבא קמא Χ¦Χ΄Χ•"
      },
      "url": "Bava_Kamma.96",
      "ref": "Bava Kamma 96",
      "order": 3,
      "category": "Talmud"
      },
   ...
	]
}

We're specifically interested in the list of items stored in the array under the field calendar_items, and we want the data in the dictionary with the title of Parashat Hashavua, so let's retrieve that.

What's most interesting to us within the Parashat Hashavua data is the ref, the specific Sefaria citation for this text. (To read more about our citation system, see Text References. It is a core aspect of working with our API).

# Retrieve the list of calendar_items
calendar_items = data['calendar_items']

# Find the dictionary in calendar_items storing the metadata for Parashat Hashavua, 
# and save the ref, as well as the name of the week's Parasha.  
for item in calendar_items:
    if item['title']['en'] == 'Parashat Hashavua':
        parasha_ref = item['ref'] 
        parasha_name = item['displayValue']['en']

Great! Now we have our citation for the specific week's Parasha. This ref will appear as a range, so for example, for the week of Parashat Mishpatim , printing parasha_ref returns Exodus 21:1-24:18, and printing parasha_name returns Mishpatim.

print(parasha_ref) # The ranged citation for the week's Parasha
print(parasha_name) # The name of the Parasha

Selecting the First Verse

For this specific tutorial, we want to limit our Dvar Torah to only the first verse from this week's Parasha. To do this, we will collect the first citation in the range; in the case of Exodus 21:1-24:18, we want only Exodus 21:1.

parasha_ref = parasha_ref.split("-")[0]
print(parasha_ref) # The first verse of this week's parasha

Please Note: This is not a requirement for the subsequent API calls. We are intentionally limiting the breadth of our text to a specific verse for the sake of the example. Please feel free to play with these calls using text citations (refs) that span multiple chapters.

Retrieving the Parasha Text

Now that we have our parasha_ref all set to contain a string citing the first verse in this week's Parasha, let's make another API call to the Texts (v3) API to retrieve the text of that verse.

url = f"https://www.sefaria.org/api/v3/texts/{parasha_ref}"

# Make GET request
response = requests.get(url)

# Parse response as JSON 
data = response.json() 

When we print data, we get a massive dictionary containing lots of data regarding the various editions of this text on Sefaria. Below is a truncated version of what's returned (notice the ... replacing data irrelevant for this tutorial).

{
  "versions": [
    {
      "status": "locked",
      "priority": 2,
      "license": "CC-BY-SA",
      "versionNotes": "<i>Miqra According to the Masorah</i> (MAM) is a digital Hebrew edition of the Tanakh based on the Aleppo Codex and related manuscripts. It is designed for readers, and as such it contains added elements to aid vocalization of the text. For instance: When an accent is marked in an unstressed syllable, an extra accent is added in the proper place (<i>pashta</i>, <i>zarqa</i>, <i>segol</i>, <i>telisha</i>). <i>Legarmeih</i> and <i>paseq</i> are visibly distinguished. <i>Qamaz qatan</i> is indicated by its designated Unicode character (alternatives are documented where traditions differ about its application).<br>The text of MAM is fully documented. The <a href=\"https://he.wikisource.org/wiki/%D7%9E%D7%A9%D7%AA%D7%9E%D7%A9:Dovi/%D7%9E%D7%A7%D7%A8%D7%90_%D7%A2%D7%9C_%D7%A4%D7%99_%D7%94%D7%9E%D7%A1%D7%95%D7%A8%D7%94/%D7%9E%D7%99%D7%93%D7%A2_%D7%A2%D7%9C_%D7%9E%D7%94%D7%93%D7%95%D7%A8%D7%94_%D7%96%D7%95\">complete introduction</a> to the edition (Hebrew) explains the types of editorial decisions that have been made and the reasons for them (<a href=\"https://en.wikisource.org/wiki/User:Dovi/Miqra_according_to_the_Masorah#About_this_Edition_(English_Abstract)\">English abstract</a>). In addition, every word in the Bible about which there is some textual concern or ambiguity includes a documentation note; these notes can be viewed conveniently <a href=\"https://bdenckla.github.io/MAM-with-doc/\">here</a>. If an error is discovered, it may be reported to <a href=\"https://he.wikisource.org/wiki/%D7%A9%D7%99%D7%97%D7%AA_%D7%9E%D7%A9%D7%AA%D7%9E%D7%A9:Dovi\">User:Dovi</a> at Hebrew Wikisource. Please check the documentation notes before reporting an error.",
      "versionTitleInHebrew": "מקרא גל Χ€Χ™ Χ”ΧžΧ‘Χ•Χ¨Χ”",
      "actualLanguage": "he",
      "languageFamilyName": "hebrew",
      "isPrimary": true,
      "direction": "rtl",
      "language": "he",
      "versionSource": "https://he.wikisource.org/wiki/%D7%9E%D7%A9%D7%AA%D7%9E%D7%A9:Dovi/%D7%9E%D7%A7%D7%A8%D7%90_%D7%A2%D7%9C_%D7%A4%D7%99_%D7%94%D7%9E%D7%A1%D7%95%D7%A8%D7%94",
      "versionTitle": "Miqra according to the Masorah",
      "text": "Χ•Φ°ΧΦ΅Φ™ΧœΦΌΦΆΧ”Φ™ Χ”Φ·ΧžΦΌΦ΄Χ©ΧΦ°Χ€ΦΌΦΈΧ˜Φ΄Φ”Χ™Χ אֲשׁ֢Φ₯Χ¨ Χͺָּשִׂ֖ים ΧœΦ΄Χ€Φ°Χ Φ΅Χ™Χ”ΦΆΦ½ΧΧƒ",
      /**Additional attributes omitted for the sake of the example**/
    }
  ],
  "available_versions": [...]
}

Inside the object inside the versions array, we can see a field called text storing the text of this verse. Let's save that to a variable, and also grab the versionTitle of this edition of the text. Since this edition of the text is in Hebrew, we'll name the variables he_vtitle and he_pasuk.

he_vtitle = data['versions'][0]['versionTitle'] 
he_pasuk = data['versions'][0]['text']

Big progress! We have our verse for the Dvar Torah outline; let's move on to the next step.

Retrieving a Different Edition of the Text

While the Hebrew verse is useful, let's also retrieve an English translation of the verse. You can query the api/v3/texts endpoint for many different editions of the text in different languages, or different versions within a language. For now, we'll just repeat what we did above, making the same GET request, but adding the query parameter version=english. (To learn more about all of our available translations, how to request specific versions, and all of the customizations, see Texts (v3)).

# Change version to English
url = f"https://www.sefaria.org/api/v3/texts/{parasha_ref}?version=english"

# Make the GET request
response = requests.get(url)

# Parse the response as JSON
data = response.json()

# Retrieve the version title, and text for the English verse.
en_vtitle = data['versions'][0]['versionTitle']
en_pasuk = data['versions'][0]['text']

Retrieving Parasha Commentaries

Fantastic progress! We have our Hebrew text of the verse, and our English text of the verse. Now we just need some commentaries to build out the rest of this outline.

To retrieve our commentaries, we're going to use the Related API endpoint, and pass in our parasha_ref as the tref (i.e. text reference).

url = f"https://www.sefaria.org/api/related/{parasha_ref}"

# Make the GET request
response = requests.get(url)

# Parse the response as JSON
data = response.json()

When we print data, we get a dictionary that has the following keys:

{
  "links": [...],
  "sheets": [...],
  "notes": [...],
  "webpages": [...],
  "topics": [...],
  "manuscripts": [...],
  "media": [...]
}

Each key points to an array containing a list of JSON objects, each representing a connection between our query text (parasha_ref) and connections of that type to other items in the library.

For example, a sample JSON object from the links array (containing all links between our query text and other linked texts) will look like this:

{
  "_id": "51611f84edbab4794f78309b",
  "index_title": "Shemot Rabbah",
  "category": "Midrash",
  "type": "midrash",
  "ref": "Shemot Rabbah 30:2",
  "anchorRef": "Exodus 21:1",
  "anchorRefExpanded": ["Exodus 21:1"],
  "sourceRef": "Shemot Rabbah 30:2",
  "sourceHeRef": "Χ©ΧžΧ•Χͺ Χ¨Χ‘Χ” ל׳:Χ‘Χ³",
  "anchorVerse": 1,
  "sourceHasEn": true,
  "compDate": [1200],
  "commentaryNum": 30.0002,
  "collectiveTitle": {
    "en": "Shemot Rabbah",
    "he": "Χ©ΧžΧ•Χͺ Χ¨Χ‘Χ”"
  },
  "heTitle": "Χ©ΧžΧ•Χͺ Χ¨Χ‘Χ”"
}

This is a link between our parasha_ref to the Midrash of Shemot Rabbah. You'll notice we're getting a lot of metadata here, but most critical for our purposes is the type of link, as well as the ref for the linking text.

The type field tells us the general type of connection between our parasha_ref and the text returned in the ref field. Some possible link types may include targum, reference, quotation, commentary, essay, midrash or parshanut among others.

For sake of simplicity, in this tutorial, let's only look at linked texts with a type of commentary.

We'll iterate through the links array in the response data, and append the ref (the citation) of all linked texts of type commentary to a list we'll call commentaries.

# Set up our commentaries list
commentaries = []

# Iterate through the "links" in our data response, filtering for commentary links, and 
# appending the text reference to our commentaries list. 
for linked_text in data["links"]:
    if linked_text['type'] == 'commentary':
        commentaries.append(linked_text['ref'])

Great! Now you have a list of all commentary links to the first verse in this week's Parasha. We are almost there!

Retrieving the Commentary Text

Our next step is to make additional calls to the Texts (v3) endpoint to retrieve the text of our commentaries. In theory, you also do some filtering here to determine exactly which commentaries you'd like in your outline.

For the sake of the brevity of this tutorial, we will just include the first three commentaries that appear in our list in the outline. Feel free to play with this! There's a lot that can be done at this stage.

Since we'll be repeating the same process three times, let's define a function get_commentary_text(ref) to help us with our text retrieval:

def get_commentary_text(ref):
  	
    # Our standard GET request, and JSON parsing
    url = f"https://www.sefaria.org/api/v3/texts/{ref}"
    response = requests.get(url)
    data = response.json()

    # Checking to make sure we have a primary version for the commentary 
    # (otherwise, the versions field would be empty). 
    if "versions" in data and len(data['versions']) > 0:
      
      # Retrieve the general name of the commentary book (i.e. "Rashi on Genesis")
      title = data['title']
      
      # Retrieve the text of the commentary
      text = data['versions'][0]['text']

      # Return the title, and the text
      return title, text

Now, we'll apply this function to the first three commentaries in our list of commentaries:

com1_title, com1_text = get_commentary_text(commentaries[0])
com2_title, com2_text = get_commentary_text(commentaries[1])
com3_title, com3_text = get_commentary_text(commentaries[2])

Congratulations! We are ready for the final step, printing our outline!

Printing your Outline

At this point, we should have the following variables defined in our code:

  • parasha - The name of the Parasha (i.e. Mishpatim,_Eikev etc)
  • parasha_ref - The specific text reference for the first verse of that Parasha (i.e. Exodus 21.1)
  • he_vtitle- The version title for the specific Hebrew edition of the text of the verse
  • he_text - The Hebrew text for the verse
  • en_vtitle - The version title for the specific English edition of the text of the verse
  • en_text - The English text for the verse
  • And lastly, as seen in the code above, the commentary title and commentary text for the first three commentaries in our commentaries list.

Now that we have everything in place, let's print it out:

print(f"My Outline for Parashat {parasha_name}")
print(f"Hebrew: {he_pasuk} (edition: {he_vtitle})")
print(f"English: {en_pasuk} (edition: {en_vtitle})")
print("\nThree Commentaries:")
print(f"A) {com1_title}: {com1_text}\n")
print(f"B) {com2_title}: {com2_text}\n")
print(f"C) {com3_title}: {com3_text}")

When we ran this code the week of Parashat Mishpatim, this is what printed:

My Outline for Parashat Mishpatim
Hebrew: Χ•Φ°ΧΦ΅Φ™ΧœΦΌΦΆΧ”Φ™ Χ”Φ·ΧžΦΌΦ΄Χ©ΧΦ°Χ€ΦΌΦΈΧ˜Φ΄Φ”Χ™Χ אֲשׁ֢Φ₯Χ¨ Χͺָּשִׂ֖ים ΧœΦ΄Χ€Φ°Χ Φ΅Χ™Χ”ΦΆΦ½ΧΧƒ (edition: Miqra according to the Masorah)
English: These are the rules that you shall set before them: (edition: The Contemporary Torah, Jewish Publication Society, 2006)

Three Commentaries:
A) Ramban on Exodus 21:1: טגם <b>Χ•ΧΧœΧ” Χ”ΧžΧ©Χ€Χ˜Χ™Χ אשר Χͺשים ΧœΧ€Χ Χ™Χ”Χ</b>, Χ›Χ™ Χ¨Χ¦Χ” ΧœΧ”Χ§Χ“Χ™Χ ΧœΧ”Χ Χ”ΧžΧ©Χ€Χ˜Χ™Χ, Χ›Χ™ כאשר Χ”Χ™Χ” Χ‘Χ’Χ©Χ¨Χͺ Χ”Χ“Χ‘Χ¨Χ•Χͺ Χ”Χ“Χ‘Χ•Χ¨ Χ”Χ¨ΧΧ©Χ•ΧŸ Χ‘Χ™Χ“Χ™Χ’Χͺ Χ”', Χ•Χ”Χ©Χ Χ™ באיבור Χ’"Χ–, Χ—Χ–Χ¨ Χ•Χ¦Χ•Χ” אΧͺ ΧžΧ©Χ” <b>Χ›Χ” Χͺאמר אל Χ‘Χ Χ™ Χ™Χ©Χ¨ΧΧœ אΧͺם ראיΧͺם Χ›Χ™ מן Χ”Χ©ΧžΧ™Χ Χ“Χ‘Χ¨ΧͺΧ™ Χ’ΧžΧ›Χ</b> (Χ©ΧžΧ•Χͺ Χ›Χ³:Χ›Χ΄Χ‘), Χ©Χͺזהירם אΧͺΧ” Χ’Χ•Χ“ Χ©Χ™ΧͺΧ Χ• ΧœΧ‘Χ ΧœΧžΧ” שראו Χ•Χ™Χ–Χ”Χ¨Χ• Χ‘ΧžΧ¦Χ•Χͺ Χ”ΧΧœΧ• Χ©Χ¦Χ•Χ™Χͺים, <b>Χ›Χ™ אΧͺם ראיΧͺם</b>, Χ›Χ Χ’Χ“ Χ“Χ‘Χ•Χ¨ <b>אנכי</b>, <b>Χ•ΧœΧ ΧͺΧ’Χ©Χ•ΧŸ אΧͺΧ™</b> Χ›Χ Χ’Χ“ <b>לא Χ™Χ”Χ™Χ” לך</b>, ΧœΧ”Χ©ΧœΧ™Χ Χ’Χ Χ™ΧŸ Χ’"Χ–, <b>Χ•ΧΧœΧ” Χ”ΧžΧ©Χ€Χ˜Χ™Χ</b> Χ›Χ Χ’Χ“ <b>לא ΧͺΧ—ΧžΧ•Χ“</b>, Χ›Χ™ אם לא Χ™Χ“Χ’ האדם מש׀ט Χ”Χ‘Χ™Χͺ או Χ”Χ©Χ“Χ” ושאר Χ”ΧžΧžΧ•ΧŸ Χ™Χ—Χ©Χ•Χ‘ שהוא Χ©ΧœΧ• Χ•Χ™Χ—ΧžΧ“Χ”Χ• Χ•Χ™Χ§Χ—Χ”Χ• ΧœΧ’Χ¦ΧžΧ•, ΧœΧ€Χ™Χ›Χš אמר <b>Χͺשים ΧœΧ€Χ Χ™Χ”Χ</b>, ΧžΧ©Χ€Χ˜Χ™Χ ישרים Χ™Χ Χ”Χ™Χ’Χ• אוΧͺם ביניהם, Χ•ΧœΧ Χ™Χ—ΧžΧ“Χ• ΧžΧ” שאינו Χ©ΧœΧ”Χ מן Χ”Χ“Χ™ΧŸ Χ•Χ›ΧŸ ΧΧžΧ¨Χ• Χ‘ΧžΧ“Χ¨Χ© Χ¨Χ‘Χ” (Χ©ΧžΧ•Χͺ ל Χ˜Χ•) Χ›Χœ Χ”ΧͺΧ•Χ¨Χ” Χ›ΧœΧ” ΧͺΧœΧ•Χ™Χ” Χ‘ΧžΧ©Χ€Χ˜, ΧœΧ›ΧŸ Χ Χͺן Χ”Χ§Χ‘"Χ” Χ“Χ™Χ Χ™ΧŸ אחר Χ’Χ©Χ¨Χͺ Χ”Χ“Χ‘Χ¨Χ•Χͺ. Χ•Χ›ΧŸ Χ™Χ€Χ¨Χ© Χ‘ΧΧœΧ” Χ”ΧžΧ©Χ€Χ˜Χ™Χ Χ”ΧžΧ©Χ€Χ˜ Χ‘Χ’Χ‘Χ•Χ“Χ” Χ–Χ¨Χ” (Χ©ΧžΧ•Χͺ Χ›Χ΄Χ‘:Χ™Χ΄Χ˜), Χ•Χ‘Χ›Χ‘Χ•Χ“ האב (שם כא Χ˜Χ• Χ™Χ–), Χ•Χ”Χ¨Χ¦Χ™Χ—Χ” (שם כא Χ™Χ‘ Χ™Χ“), והניאוף (שם Χ›Χ‘ Χ™Χ—), הנזכרים Χ‘Χ’Χ©Χ¨Χͺ Χ”Χ“Χ‘Χ¨Χ•Χͺ:  <br><b>Χ•Χ“Χ¨Χ©Χ•</b> ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ כנגנים (ΧͺΧ Χ—Χ•ΧžΧ א, Χ’Χ™Χ˜Χ™ΧŸ Χ€Χ—:), ΧžΧ€Χ Χ™ Χ©Χ”Χ™Χ” ראוי ΧœΧ•ΧžΧ¨ אשר Χͺשים ΧœΧ”Χ, Χ›ΧžΧ• שאמר (Χ©ΧžΧ•Χͺ Χ˜Χ΄Χ•:Χ›Χ΄Χ”) שם שם ΧœΧ• Χ—Χ§ Χ•ΧžΧ©Χ€Χ˜, Χ•ΧΧžΧ¨ ΧœΧ€Χ Χ™Χ”Χ, שהם Χ™Χ”Χ™Χ• Χ”Χ“Χ™Χ™Χ Χ™ΧŸ, Χ›Χ™ גל Χ”Χ©Χ•Χ€Χ˜ יבא Χ”ΧœΧ©Χ•ΧŸ Χ”Χ–Χ”, Χ•Χ’ΧžΧ“Χ• Χ©Χ Χ™ האנשים אשר ΧœΧ”Χ Χ”Χ¨Χ™Χ‘ ΧœΧ€Χ Χ™ Χ”' ΧœΧ€Χ Χ™ הכהנים Χ•Χ”Χ©Χ•Χ€Χ˜Χ™Χ (דברים Χ™Χ˜ Χ™Χ–), Χ’Χ“ Χ’ΧžΧ“Χ• ΧœΧ€Χ Χ™ Χ”Χ’Χ“Χ” למש׀ט (Χ‘ΧžΧ“Χ‘Χ¨ ΧœΧ” Χ™Χ‘), ΧœΧ€Χ Χ™ Χ›Χœ Χ™Χ•Χ“Χ’Χ™ Χ“Χͺ Χ•Χ“Χ™ΧŸ (אבΧͺΧ¨ א Χ™Χ’) Χ•Χ“Χ¨Χ©Χ• Χ’Χ•Χ“ (שם) ΧœΧ€Χ Χ™Χ”Χ, Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ”Χ“Χ™Χ•Χ˜Χ•Χͺ, ΧžΧ€Χ Χ™ Χ©Χ›ΧͺΧ‘ Χ‘ΧžΧ©Χ€Χ˜Χ™Χ Χ•Χ”Χ’Χ™Χ©Χ• אדוניו אל Χ”ΧΧœΧ”Χ™Χ (Χ©ΧžΧ•Χͺ כ״א:Χ•Χ³), Χ’Χ“ Χ”ΧΧœΧ”Χ™Χ יבא Χ“Χ‘Χ¨ שניהם (Χ©ΧžΧ•Χͺ Χ›Χ΄Χ‘:Χ—Χ³), Χ•Χ›ΧͺΧ•Χ‘ גם Χ›ΧŸ Χ•Χ Χͺן Χ‘Χ€ΧœΧ™ΧœΧ™Χ (Χ©ΧžΧ•Χͺ כ״א:Χ›Χ΄Χ‘), שהם Χ”Χ“Χ™Χ™Χ Χ™ΧŸ Χ”ΧžΧ•ΧžΧ—Χ™ΧŸ Χ”Χ‘ΧžΧ•Χ›Χ™Χ Χ’Χ“ ΧžΧ©Χ” Χ¨Χ‘Χ™Χ Χ•:  <b>Χ•ΧœΧ›Χš</b> אמר Χ‘Χ›ΧΧŸ Χ©Χ”ΧžΧ©Χ€Χ˜Χ™Χ Χ”ΧΧœΧ” Χ™Χ©Χ™ΧžΧ• אוΧͺם ΧœΧ€Χ Χ™ Χ”ΧΧœΧ”Χ™Χ Χ©Χ™Χ–Χ›Χ™Χ¨, Χ•ΧœΧ ΧœΧ€Χ Χ™ גוים, Χ•ΧœΧ ΧœΧ€Χ Χ™ ΧžΧ™ שאינו Χ©Χ•Χ€Χ˜ גל Χ€Χ™ Χ”ΧͺΧ•Χ¨Χ”, והוא Χ”Χ“Χ™Χ•Χ˜ ΧœΧ–Χ”, שאבור ΧœΧ‘Χ Χ‘Χ€Χ Χ™Χ• כשם שאבור ΧœΧ‘Χ ΧœΧ€Χ Χ™ הגוים ואג"Χ€ Χ©Χ™Χ“Χ•Χ’ Χ©Χ”Χ”Χ“Χ™Χ•Χ˜ Χ”Χ–Χ” Χ™Χ•Χ“Χ’ Χ©Χ•Χ¨Χͺ Χ”Χ“Χ™ΧŸ Χ•Χ™Χ“Χ™ΧŸ ΧœΧ• Χ›Χ”Χ•Χ’ΧŸ, ΧΧ‘Χœ הוא אבור ΧœΧ©Χ•ΧžΧ• Χ“Χ™Χ™ΧŸ Χ•ΧœΧ¦Χ’Χ•Χ§ ΧœΧ• Χ©Χ™Χ›Χ•Χ£ אΧͺ Χ‘Χ’Χœ Χ“Χ™Χ Χ• ΧœΧ“Χ•ΧŸ ΧœΧ€Χ Χ™Χ•, Χ•Χ”Χ”Χ“Χ™Χ•Χ˜ Χ’Χ¦ΧžΧ• אבור ΧœΧ“Χ•ΧŸ ΧœΧ”Χ. ואף גל Χ€Χ™ Χ©Χ”Χ–Χ›Χ™Χ¨Χ• Χ—Χ›ΧžΧ™Χ Χ©ΧͺΧ™ Χ”Χ›ΧͺΧ•Χͺ Χ”ΧΧœΧ” כאחΧͺ, Χ™Χ© Χ”Χ€Χ¨Χ© ביניהם, שאם Χ¨Χ¦Χ• Χ©Χ Χ™ Χ‘Χ’ΧœΧ™ Χ”Χ“Χ™ΧŸ ΧœΧ‘Χ ΧœΧ€Χ Χ™ Χ”Χ”Χ“Χ™Χ•Χ˜ Χ©Χ‘Χ™Χ©Χ¨ΧΧœ ΧžΧ•ΧͺΧ¨ הוא, Χ•Χ‘Χ“Χ§Χ‘ΧœΧ•Χ Χ’Χ™ΧœΧ•Χ™Χ”Χ• Χ“Χ™Χ Χ• Χ“Χ™ΧŸ, ΧΧ‘Χœ ΧœΧ€Χ Χ™ הגוים ΧΧ‘Χ•Χ¨Χ™ΧŸ הם ΧœΧ‘Χ ΧœΧ€Χ Χ™Χ• Χ©Χ™Χ“Χ•ΧŸ ΧœΧ”Χ בדיניהם ΧœΧ’Χ•ΧœΧ, Χ•ΧΧ€Χ™ΧœΧ• Χ”Χ™Χ• דיניהם Χ›Χ“Χ™Χ Χ Χ• באוΧͺΧ• Χ’Χ Χ™ΧŸ:  

B) Kli Yakar on Exodus 21:1: <b>Χ•Χ‘Χ–Χ” ΧžΧ™Χ•Χ©Χ‘ Χ’"Χ›,</b> ΧžΧ” Χ”Χ™Χ” Χ”Χ¦Χ•Χ¨Χš Χ”Χ’Χ“Χ•Χœ ΧœΧ¦Χ•Χͺ ΧœΧ”Χ גל Χ’Χ©Χ™Χ™Χͺ Χ”ΧžΧ–Χ‘Χ— Χ‘Χ©ΧœΧžΧ Χ”Χ“Χ™Χ Χ™ΧŸ Χ”Χ™Χ” Χ¦Χ•Χ¨Χš Χ©Χ’Χ” ΧΧ‘Χœ Χ”ΧžΧ–Χ‘Χ— לא Χ”Χ™Χ” Χ›Χœ Χ›Χš Χ¦Χ•Χ¨Χš Χ©Χ’Χ” Χ›Χ™ Χ’Χ“Χ™Χ™ΧŸ לא Χ Χ¦Χ˜Χ•Χ• גל Χ”ΧžΧ©Χ›ΧŸ, אלא ודאי ΧœΧ›Χš הקדים ΧžΧœΧΧ›Χͺ Χ”ΧžΧ–Χ‘Χ— אל Χ€Χ¨' ΧžΧ©Χ€Χ˜Χ™Χ ΧœΧ•ΧžΧ¨ לך Χ©Χͺשים Χ”Χ‘Χ Χ”Χ“Χ¨Χ™ΧŸ אצל Χ”ΧžΧ–Χ‘Χ— Χ›Χ“Χ™ Χ©Χ™ΧœΧžΧ“Χ• מן Χ”ΧžΧ–Χ‘Χ— Χ©Χ›Χœ ΧžΧ” Χ©Χ€Χ•Χ‘Χœ Χ‘ΧžΧ–Χ‘Χ— Χ€Χ•Χ‘Χœ גם Χ‘Χ‘Χ Χ”Χ“Χ¨Χ™ΧŸ.  

C) Mizrachi, Exodus 21:1: <b>ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים Χ›Χ•'. </b>Χ‘Χ’Χ˜Χ™ΧŸ Χ€Χ¨Χ§ Χ”ΧžΧ’Χ¨Χ© Χ•Χ€Χ¨Χ©"Χ™ Χ“ΧœΧ€Χ Χ™Χ”Χ קא אג' זקנים Χ©Χ’ΧœΧ• Χ’ΧžΧ• ΧœΧ”Χ¨ קודם מΧͺן ΧͺΧ•Χ¨Χ” Χ›Χ“Χ›ΧͺΧ™Χ‘ Χ•ΧΧœ ΧžΧ©Χ” אמר Χ’ΧœΧ” Χ•Χ’Χ•' Χ€Χ™Χ¨Χ•Χ© שהם Χ›ΧœΧ Χ‘ΧžΧ•Χ›Χ™Χ Χ•ΧžΧ™Χ§Χ¨Χ• ΧΧœΧ”Χ™Χ Χ•ΧΧ™ΧžΧ’Χ•Χ˜ ΧžΧœΧ€Χ Χ™Χ”Χ ΧΧ€Χ™ΧœΧ• Χ™Χ©Χ¨ΧΧœΧ™Χ Χ”Χ“Χ™Χ•Χ˜Χ•Χͺ Χ•Χ›Χœ Χ©Χ›ΧŸ Χ›Χ•Χͺים א"Χ  קרא Χ“ΧœΧ€Χ Χ™Χ”Χ ΧΧ”ΧΧœΧ”Χ™Χ Χ“Χ›ΧͺΧ™Χ‘ Χ‘Χ€Χ¨Χ©Χ” קאי Χ›Χ“Χ€Χ¨Χ™Χš ואם Χͺאמר הא ΧžΧœΧ€Χ Χ™Χ”Χ Χ“Χ¨Χ©Χ™Χ ΧŸ ΧœΧ’Χ™Χœ Χ©Χ—Χ™Χ™Χ‘ ΧœΧ”Χ¨ΧΧ•Χͺ ΧœΧ• ׀נים או Χ›Χ©ΧœΧ—ΧŸ Χ”Χ’Χ¨Χ•Χš Χ•ΧžΧ•Χ›ΧŸ ΧœΧ€Χ Χ™ האדם Χ›Χ’Χ Χ™Χ™ΧŸ שנאמר אΧͺΧ” הראΧͺ ΧœΧ“Χ’Χͺ Χ™Χ© ΧœΧ•ΧžΧ¨ ΧžΧ“Χ”"ל ΧœΧžΧ›ΧͺΧ‘ אשר Χͺשים ΧœΧ€Χ Χ™Χ”Χ Χ©"מ ΧœΧžΧ’Χ•Χ˜Χ™ Χ›Χ•Χͺים Χ•ΧžΧ” Χ©Χ›ΧͺΧ‘ Χ”Χ¨ΧžΧ‘"ן Χ•Χ“Χ¨Χ©Χ• ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים ΧžΧ€Χ Χ™ Χ©Χ”Χ™Χ” ראוי ΧœΧ•ΧžΧ¨ אשר Χͺשים ΧœΧ”Χ Χ›ΧžΧ• שאמר שם שם ΧœΧ• Χ—Χ§ Χ•ΧžΧ©Χ€Χ˜ Χ•ΧΧžΧ¨ ΧœΧ€Χ Χ™Χ”Χ שהם Χ™Χ”Χ™Χ• הדיינים Χ›Χ™ גל Χ”Χ©Χ•Χ€Χ˜ יבא Χ”ΧœΧ©Χ•ΧŸ Χ”Χ–Χ” Χ•Χ’ΧžΧ“Χ• Χ©Χ Χ™ האנשים אשר ΧœΧ”Χ Χ”Χ¨Χ™Χ‘ ΧœΧ€Χ Χ™ הכהנים Χ•Χ”Χ©Χ•Χ€Χ˜Χ™Χ Χ’Χ“ Χ’ΧžΧ“Χ• ΧœΧ€Χ Χ™ Χ”Χ’Χ“Χ” למש׀ט ΧœΧ€Χ Χ™ Χ›Χœ Χ™Χ•Χ“Χ’Χ™ Χ“Χͺ Χ•Χ“Χ™ΧŸ אינו ΧžΧ—Χ•Χ•Χ¨ Χ›Χ™ Χ›Χ‘Χ¨ Χ“Χ¨Χ©Χ• Χ”ΧœΧ©Χ•ΧŸ ΧžΧ’Χ Χ™Χ™ΧŸ ׀נים וא׀שר שהוא Χ‘Χ•Χ‘Χ¨ Χ©Χ§Χ•Χœ הוא ויבאו שניהם והא Χ“Χ Χ§Χ˜ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים Χ•ΧœΧ נקט Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ”Χ“Χ™Χ•Χ˜Χ•Χͺ Χ›Χ“Χͺניא Χ‘Χ€Χ¨Χ§ Χ”ΧžΧ’Χ¨Χ© Χ•Χ›Χœ Χ©Χ›ΧŸ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים ΧžΧ©Χ•Χ Χ“ΧžΧ™Χ’Χ•Χ˜Χ Χ“Χ”Χ“Χ™Χ•Χ˜Χ•Χͺ אינו Χ“Χ•ΧžΧ” ΧœΧžΧ™Χ’Χ•Χ˜Χ Χ“Χ›Χ•Χͺים דאף גל Χ’Χ‘ Χ“ΧͺΧ¨Χ•Χ™Χ”Χ• מקרא Χ“ΧœΧ€Χ Χ™Χ”Χ קא ΧžΧžΧ’Χ˜Χ™ ΧœΧ”Χ• Χ‘Χ‘Χ¨Χ™Χͺא Χ“Χ”ΧžΧ’Χ¨Χ© מ"מ Χ™Χ© Χ”Χ€Χ¨Χ© ביניהם Χ“ΧžΧ™Χ’Χ•Χ˜Χ Χ“ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ”Χ“Χ™Χ•Χ˜Χ•Χͺ אינו אלא Χ“ΧœΧ ΧžΧ¦Χ• ΧœΧΧ›Χ€Χ•Χ™Χ™ ΧœΧ‘Χ’ΧœΧ™ Χ”Χ¨Χ™Χ‘ ΧœΧ‘Χ ΧœΧ”Χ“Χ™Χ™ΧŸ ΧœΧ€Χ Χ™Χ”Χ ΧΧ‘Χœ אם Χ¨Χ¦Χ• ΧœΧ‘Χ ΧœΧ€Χ Χ™Χ”Χ ΧžΧ•ΧͺΧ¨ ודיניהם Χ“Χ™ΧŸ Χ•ΧΧœΧ• ΧžΧ’Χ•Χ˜Χ Χ“ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים ΧΧ€Χ™ΧœΧ• אם Χ™Χ¨Χ¦Χ• ΧœΧ‘Χ ΧœΧ€Χ Χ™Χ”Χ ΧœΧ”Χ“Χ™Χ™ΧŸ בדיניהם אבור Χ•Χ”Χ™Χ™Χ Χ• Χ“ΧžΧ‘Χ™Χ™Χ Χ‘Χ” Χ©Χ”ΧžΧ‘Χ™Χ Χ“Χ™Χ Χ™ Χ™Χ©Χ¨ΧΧœ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים ΧžΧ—ΧœΧœ אΧͺ השם Χ•ΧžΧ™Χ§Χ¨ שם Χ’Χ‘Χ•Χ“' כוכבים והא Χ“Χ§ΧΧžΧ¨ וא׀י' Χ™Χ“Χ’Χͺ Χ‘Χ“Χ™ΧŸ אחד Χ©Χ›Χ•Χͺים Χ“Χ Χ™ΧŸ אוΧͺΧ• Χ›Χ“Χ™Χ Χ Χ• אינו Χ¨Χ•Χ¦Χ” ΧœΧ•ΧžΧ¨ Χ“ΧžΧžΧ™Χ’Χ•Χ˜' Χ“ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים Χ©ΧžΧ’Χ™Χ ΧŸ Χ‘Χ™ΧŸ Χ‘Χ“Χ Χ™ΧŸ Χ›Χ“Χ™Χ Χ Χ• Χ‘Χ™ΧŸ Χ‘ΧΧ™ΧŸ Χ“Χ Χ™ΧŸ Χ›Χ“Χ™Χ Χ Χ• Χ“Χ‘ΧΧ™ΧŸ Χ“Χ Χ™ΧŸ Χ›Χ“Χ™Χ Χ Χ• לא Χ¦Χ¨Χ™Χš קרא ΧœΧžΧ™Χ’Χ•Χ˜Χ Χ“ΧͺΧ€Χ•Χ§ ΧœΧ™ ΧžΧ©Χ•Χ Χ’Χ–Χœ אלא Χ”Χ›Χ™ Χ€Χ™Χ¨Χ•Χ©Χ” לא ΧžΧ‘Χ’Χ™Χ Χ‘Χ©ΧΧ™ΧŸ Χ“Χ Χ™ΧŸ Χ›Χ“Χ™Χ Χ Χ• דההוא ΧͺΧ€Χ™Χ§ ΧœΧ™ ΧžΧ©Χ•Χ Χ’Χ–Χœ אלא ΧΧ€Χ™ΧœΧ• Χ‘Χ©Χ“Χ Χ™ΧŸ Χ›Χ“Χ™Χ Χ Χ• אל Χͺביאהו בגרכאוΧͺ Χ©ΧœΧ”Χ ΧžΧžΧ™Χ’Χ•Χ˜Χ Χ“ΧœΧ€Χ Χ™Χ”Χ Χ•ΧœΧ ΧœΧ€Χ Χ™ Χ›Χ•Χͺים אי Χ ΧžΧ™ ΧΧ€Χ™ΧœΧ• Χ‘ΧΧ™ΧŸ Χ“Χ Χ™ΧŸ Χ›Χ“Χ™Χ Χ Χ• אצטרך קרא ΧœΧžΧ™Χ’Χ•Χ˜Χ Χ“Χ‘Χ“"א דינא Χ“ΧžΧœΧ›Χ•Χͺא דינא כדאיΧͺא Χ‘Χ€Χ¨Χ§ קמא   Χ“Χ’Χ™Χ˜Χ™ΧŸ Χ•ΧΧ™ΧŸ Χ›ΧΧŸ ΧžΧ©Χ•Χ Χ’Χ–Χœ: 
πŸŽ‰

Congratulations! You have officially written a script to generate a D'var Torah outline for the weekly Parasha!

We invite you to dive deeper into our API, and all of the infinite possibilities with our data in the documentation. Looking forward to seeing what you can build!

The Full Code

The full code for the script can be seen below. The code has been slightly refactored and reorganized for better readability and code reuse within this script. The stages are marked in the comments.

import requests


# Helper functions

def get_request_json_data(endpoint, ref=None, param=None):
    url = f"https://www.sefaria.org/{endpoint}"

    if ref:
        url += f"{ref}"

    if param:
        url += f"?{param}"

    response = requests.get(url)
    data = response.json()
    return data


def get_commentary_text(ref):
    data = get_request_json_data("api/v3/texts/", ref)

    # Checking to make sure we have a primary version for the commentary
    # (otherwise, the versions field would be empty).
    if "versions" in data and len(data['versions']) > 0:
        # Retrieve the general name of the commentary book (i.e. "Rashi on Genesis")
        title = data['title']

        # Retrieve the text of the commentary
        text = data['versions'][0]['text']

        # Return the title, and the text
        return title, text


if __name__ == '__main__':

    # Step One: Get the Parasha Data Using the Calendars API
    data = get_request_json_data("api/calendars")

    # Retrieve the list of calendar_items
    calendar_items = data['calendar_items']

    # Find the dictionary in calendar_items storing the metadata for Parashat Hashavua,
    # and save the ref, as well as the name of the week's Parasha.
    for item in calendar_items:
        if item['title']['en'] == 'Parashat Hashavua':
            parasha_ref = item['ref']
            parasha_name = item['displayValue']['en']

    ##################################################################

    # Step Two: Split the Ranged Ref to get the First Verse
    parasha_ref = parasha_ref.split("-")[0]

    ##################################################################

    # Step Three: Retrieve Text for the Verse
    data = get_request_json_data("api/v3/texts/", parasha_ref)
    he_vtitle = data['versions'][0]['versionTitle']
    he_pasuk = data['versions'][0]['text']

    # Change version to English - Retrieve the version title, and text for the English verse.
    data = get_request_json_data("api/v3/texts/", parasha_ref, "version=english")
    en_vtitle = data['versions'][0]['versionTitle']
    en_pasuk = data['versions'][0]['text']

    ##################################################################

    # Step Four: Get Commentaries
    data = get_request_json_data("api/related/", parasha_ref)

    # Set up our commentaries list
    commentaries = []

    # Iterate through the "links" in our data response, filtering for commentary links, and
    # appending the text reference to our commentaries list.
    for linked_text in data["links"]:
        if linked_text['type'] == 'commentary':
            commentaries.append(linked_text['ref'])

    com1_title, com1_text = get_commentary_text(commentaries[0])
    com2_title, com2_text = get_commentary_text(commentaries[1])
    com3_title, com3_text = get_commentary_text(commentaries[2])

    ##################################################################

    # Step Five: Print Parasha Outline

    print(f"My Outline for Parashat {parasha_name}")
    print(f"Hebrew: {he_pasuk} (edition: {he_vtitle})")
    print(f"English: {en_pasuk} (edition: {en_vtitle})")
    print("\nThree Commentaries:")
    print(f"A) {com1_title}: {com1_text}\n")
    print(f"B) {com2_title}: {com2_text}\n")
    print(f"C) {com3_title}: {com3_text}")

Note: The functions in this script were not written to par with adequate testing and try/except blocks that you would expect for more robust API calls. We intentionally wrote code that was as simple and bare-bones as possible to allow beginners to focus on a first attempt at using the API to retrieve data. We hope this is a helpful first step!