sefaria

package module
v0.0.0-...-8b90e50 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2025 License: MIT Imports: 20 Imported by: 0

README

go-sefaria

Go Report Card GoDoc Go Version

A Go client library for the Sefaria API, providing programmatic access to Sefaria's vast library of Jewish texts and resources.

About Sefaria

Sefaria is a non-profit organization dedicated to building the future of Jewish learning in an open and participatory way. Their platform provides access to thousands of Jewish texts including Tanakh, Talmud, Mishnah, and many other sources in multiple languages.

This client library (and the CLI tool) is not affiliated with Sefaria but is built to facilitate easy access to their API for Go developers.

Features

  • Comprehensive API Coverage: Access to all major Sefaria API endpoints
  • Multiple Services: Text retrieval, index exploration, calendar information, lexicon lookups, topic discovery, and term completions
  • Bidirectional Text Support: Built-in handling for Hebrew and Arabic text with proper RTL/LTR rendering
  • Robust HTTP Client: Retry logic, validation, and comprehensive error handling
  • Flexible Configuration: Customizable endpoints, logging, and HTTP clients
  • CLI Tool: Command-line interface for interactive use and scripting

Installation

go get github.com/ryanfaerman/go-sefaria

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ryanfaerman/go-sefaria"
)

func main() {
    // Create a new client
    client := sefaria.NewClient()

    // Get text from Genesis 1:1
    text, err := client.Text.Get(context.Background(), "Genesis 1:1", nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Reference: %s\n", text.Ref)
    fmt.Printf("Text: %s\n", text.Text[0])
}

Data normalization and alterations

The data from sefaria comes from many sources and has some inconsistencies. This library attempts to normalize the data as much as possible, but some alterations are made to the data to improve usability:

  • Replace typographic punctuation with ASCII equivalents (e.g., curly quotes to straight quotes)
  • Add bidirectional unicode markers to Hebrew and Arabic text for proper rendering (see bidi notes below)
Bidirectional Text Support

The library includes comprehensive support for Hebrew and Arabic text through the bidi package:

import "github.com/ryanfaerman/go-sefaria/bidi"

// Create a bidirectional-aware writer
writer := bidi.NewWriter(os.Stdout, true)

// Use with Hebrew text
hebrewText := bidi.String("בראשית ברא אלהים")
fmt.Fprintf(writer, "Hebrew: %s\n", hebrewText)

Configuration

Customize the client with various options:

client := sefaria.NewClient(
    sefaria.WithAPIEndpoint("https://custom-sefaria.org/api"),
    sefaria.WithLogger(logger),
    sefaria.WithHTTPClient(customHTTPClient),
)

CLI Tool

The package includes a command-line tool for interactive use:

# Install the CLI
go install github.com/ryanfaerman/go-sefaria/cmd/sefaria@latest

# Get text
sefaria text get "Genesis 1:1"

# Search terms
sefaria terms completions "torah"

# Get calendar info
sefaria calendar get

# Multiple output formats
sefaria text get "Genesis 1:1" --output-format=yaml

Requirements

  • Go 1.25.0 or later
  • Internet connection for API access

License

This project is licensed under the MIT License. See the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrEmptyTerm = fmt.Errorf("term cannot be empty")
View Source
var ErrInvalidParsha = errors.New("invalid parsha")
View Source
var Parshiot = []string{
	"Bereshit",
	"Noach",
	"Lech-Lecha",
	"Vayera",
	"Chayei Sara",
	"Toldot",
	"Vayetzei",
	"Vayishlach",
	"Vayeshev",
	"Miketz",
	"Vayigash",
	"Vayechi",
	"Shemot",
	"Vaera",
	"Bo",
	"Beshalach",
	"Yitro",
	"Mishpatim",
	"Terumah",
	"Tetzaveh",
	"Ki Tisa",
	"Vayakhel",
	"Pekudei",
	"Vayikra",
	"Tzav",
	"Shmini",
	"Tazria",
	"Metzora",
	"Achrei Mot",
	"Kedoshim",
	"Emor",
	"Behar",
	"Bechukotai",
	"Bamidbar",
	"Nasso",
	"Beha'alotcha",
	"Sh'lach",
	"Korach",
	"Chukat",
	"Balak",
	"Pinchas",
	"Matot",
	"Masei",
	"Devarim",
	"Vaetchanan",
	"Eikev",
	"Re'eh",
	"Shoftim",
	"Ki Teitzei",
	"Ki Tavo",
	"Nitzavim",
	"Vayeilech",
	"Ha’azinu",
	"Vezot Haberakhah",
	"Vayakhel-Pekudei",
	"Tazria-Metzora",
	"Achrei Mot-Kedoshim",
	"Behar-Bechukotai",
	"Chukat-Balak",
	"Matot-Masei",
	"Nitzavim-Vayeilech",
}

Functions

This section is empty.

Types

type BilingualString

type BilingualString struct {
	English string      `json:"en,omitempty"`
	Hebrew  bidi.String `json:"he,omitempty"`
}

func (BilingualString) String

func (bs BilingualString) String() string

type CalendarGetOptions

type CalendarGetOptions struct {
	Diaspora types.BoolInt `url:"diaspora,omitempty"`
	Custom   string        `url:"custom,omitempty"`
	Year     int           `url:"year,omitempty"`
	Month    int           `url:"month,omitempty"`
	Day      int           `url:"day,omitempty"`
	TimeZone string        `url:"timezone,omitempty"`
}

type CalendarService

type CalendarService service

func (*CalendarService) Get

func (*CalendarService) NextRead

func (s *CalendarService) NextRead(ctx context.Context, parsha string) (*ParshaReading, error)

type Client

type Client struct {
	BaseURL   *url.URL
	UserAgent string

	Normalizers []normalizer.Normalizer

	Text     *TextService
	Index    *IndexService
	Related  *RelatedService
	Calendar *CalendarService
	Lexicon  *LexiconService
	Topics   *TopicService
	Terms    *TermService
	// contains filtered or unexported fields
}

func NewClient

func NewClient(opts ...ClientOption) *Client

func (*Client) Do

func (c *Client) Do(req *http.Request, v any) (*http.Response, error)

func (*Client) NewRequest

func (c *Client) NewRequest(ctx context.Context, method string, u *url.URL, body any, opts ...RequestOption) (*http.Request, error)

type ClientOption

type ClientOption func(*Client)

func WithAPIEndpoint

func WithAPIEndpoint(endpoint string) ClientOption

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) ClientOption

func WithLogger

func WithLogger(logger *slog.Logger) ClientOption

type DictionaryEntry

type DictionaryEntry map[string]any

type Haftorah

type Haftorah struct {
	Title        BilingualString `json:"title" table:"Title"`
	DisplayValue BilingualString `json:"displayValue"`
	URL          string          `json:"url"`
	Ref          string          `json:"ref"`
	Order        int             `json:"order"`
	Category     string          `json:"category"`
}

type Index

type Index map[string]any

type IndexService

type IndexService service

func (*IndexService) Contents

func (s *IndexService) Contents(ctx context.Context) (*Index, error)

func (*IndexService) Get

func (s *IndexService) Get(ctx context.Context, title string) (*Index, error)

func (*IndexService) Shape

func (s *IndexService) Shape(ctx context.Context, title string, opts *IndexShapeOptions) ([]Shape, error)

type IndexShapeOptions

type IndexShapeOptions struct {
	Depth      int  `url:"depth,omitempty"`
	Dependents bool `url:"dependents,omitempty"`
}

type LearningSchedule

type LearningSchedule struct {
	Date      types.Date          `json:"date"`
	Timezone  string              `json:"timezone"`
	Learnings []ScheduledLearning `json:"calendar_items"`
}

type LexiconCompletionsOptions

type LexiconCompletionsOptions struct {
	Limit int `url:"limit,omitempty"`
}

type LexiconGetOptions

type LexiconGetOptions struct {
	LookupRef        string `url:"lookup_ref,omitempty"`
	NeverSplit       bool   `url:"never_split,omitempty"`
	AlwaysSplit      bool   `url:"always_split,omitempty"`
	AlwaysConsonants bool   `url:"always_consonants,omitempty"`
}

type LexiconService

type LexiconService service

func (*LexiconService) Completions

func (s *LexiconService) Completions(ctx context.Context, word string, lexicon string, opts *LexiconCompletionsOptions) ([][]string, error)

func (*LexiconService) Get

type Links map[string]any

type Manuscript

type Manuscript struct {
	ManuscriptSlug    string   `json:"manuscript_slug"`
	PageID            string   `json:"page_id"`
	ImageURL          string   `json:"image_url"`
	ThumbnailURL      string   `json:"thumbnail_url"`
	AnchorRef         string   `json:"anchorRef"`
	AnchorRefExpanded []string `json:"anchorRefExpanded"`
	Manuscript        struct {
		Slug          string `json:"slug"`
		Title         string `json:"title"`
		HeTitle       string `json:"he_title"`
		Source        string `json:"source"`
		Description   string `json:"description"`
		HeDescription string `json:"he_description"`
	} `json:"manuscript"`
}

type Parsha

type Parsha struct {
	Title        BilingualString `json:"title"`
	DisplayValue BilingualString `json:"displayValue"`
	URL          string          `json:"url"`
	Ref          string          `json:"ref"`
	HeRef        bidi.String     `json:"heRef"`
	Order        int             `json:"order" table:"-"`
	Category     string          `json:"category"`
	ExtraDetails struct {
		Aliyot []string `json:"aliyot"`
	} `json:"extraDetails"`
	Description BilingualString `json:"description"`
}

type ParshaReading

type ParshaReading struct {
	Parsha     Parsha          `json:"parasha"`
	Haftorah   []Haftorah      `json:"haftarah" table:"Haftorah"`
	Date       types.Date      `json:"date"`
	HebrewDate BilingualString `json:"he_date"`
}

type RandomTextOptions

type RandomTextOptions struct {
	Titles     []string
	Categories []string
}

type RelatedContent

type RelatedContent map[string]any

type RelatedLinksOptions

type RelatedLinksOptions struct {
	WithText       bool `url:"with_text,omitempty"`
	WithSheetLinks bool `url:"with_sheet_links,omitempty"`
}

type RelatedService

type RelatedService service

func (*RelatedService) Get

func (s *RelatedService) Get(ctx context.Context, tref string) (*RelatedContent, error)
func (s *RelatedService) TopicLinks(ctx context.Context, tref string) (*Links, error)

type RequestOption

type RequestOption func(req *http.Request)

type ScheduledLearning

type ScheduledLearning struct {
	Title        BilingualString `json:"title"`
	DisplayValue BilingualString `json:"displayValue"`
	Description  BilingualString `json:"description"`

	URL   string      `json:"url"`
	Ref   string      `json:"ref"`
	HeRef bidi.String `json:"heRef"`

	Order    int    `json:"order"`
	Category string `json:"category"`

	ExtraDetails struct {
		Aliyot []string `json:"aliyot,omitempty"`
	} `json:"extraDetails"`
}

type Shape

type Shape struct {
	Section   string `json:"section"`
	IsComplex bool   `json:"isComplex"`
	Length    int    `json:"length"`
	Book      string `json:"book"`
	HeBook    string `json:"heBook"`
	Chapters  []int  `json:"chapters"`
}

type Term

type Term struct {
	// Name of the Term. Since a Term is a shared title node that
	// can be referenced and used by many different Index nodes, the
	// name field is critical as it contains the shared title.
	Name string `json:"name" table:"Name"`

	// Array of Alternative Titles for the Term in Hebrew and English.
	Titles []TermTitle `json:"titles"`

	// A shared scheme to for a group of terms.
	Scheme string `json:"scheme"`

	// Terms that share a scheme can be ordered within that scheme. So for
	// example, Parshiyot within the Parasha scheme can be ordered
	// as per the order of the Parshiyot.
	Order int `json:"order"`

	// A string representing a citation to a Jewish text. A valid Ref consists
	// of a title string followed optionally by a section string or a segment
	// string. A title string is any one of the known text titles or title
	// variants in the Sefaria Database.
	Ref string `json:"ref"`

	// The category of a specific term.
	Category string `json:"category"`
}

type TermCompletion

type TermCompletion struct {
	Title      string   `json:"title" table:"Title"`
	Key        string   `json:"key" table:"Key"`
	Type       string   `json:"type" table:"Type"`
	PictureURL string   `json:"pic,omitempty"`
	Primary    bool     `json:"is_primary" table:"Primary"`
	Order      int      `json:"order"`
	TopicPools []string `json:"topic_pools,omitempty"`
}

type TermCompletions

type TermCompletions struct {
	// The language of the completions, either "en" or "he"
	Lang string `json:"lang"`

	// The type of terms returned. Possible values are:
	// - ref
	// - Topic
	// - AuthorTopic
	// - PersonTopic
	// - User
	Type string `json:"type"`

	// A list of autocompletion responses for the submitted text, as the API returns it.
	CompletionTitles []string         `json:"completions"`
	Completions      []TermCompletion `json:"completion_objects"`

	// IsBook=true if the submitted text is a book level reference. e.g. (Genesis)
	IsBook bool `json:"is_book"`

	// IsSection=true if the submitted text is a section Ref (e.g. Genesis 4, as opposed
	// to a segment Ref such as Genesis 4.1).
	IsSection bool `json:"is_section"`

	// IsSegment=true if the submitted text is a segment level Ref (e.g. Genesis 43:3, as
	// opposed to a section Ref such as Genesis 43)
	IsSegment bool `json:"is_segment"`

	// IsRange=true if the submitted text is a a ranged Ref (one that spans multiple
	// sections or segments.) e.g. Genesis 4-5
	IsRange bool `json:"is_range"`

	// If type=ref, this returns the canonical ref for the submitted text.
	Ref string `json:"ref"`

	// If type=ref, this returns the URL path to link to the submitted text on Sefaria.org
	URL string `json:"url"`

	// If type=ref, this returns the canonical name of the index of the submitted text.
	Index string `json:"index"`

	// If the submitted response is a Ref, this returns the book it belongs to.
	Book string `json:"book"`

	InternalSections   []int `json:"internalSections"`
	InternalToSections []int `json:"internalToSections"`

	Sections   []string `json:"sections"`
	ToSections []string `json:"toSections"`
	Examples   []any    `json:"examples"`

	// Given a reference, this returns the names of the sections and segments at
	// each depth of that text.
	SectionNames       []string      `json:"sectionNames"`
	HebrewSectionNames []bidi.String `json:"heSectionNames"`

	// Given a partial Ref, this will return an array of strings of possible ways
	// that it might be completed.
	AddressExamples       []string      `json:"addressExamples"`
	HebrewAddressExamples []bidi.String `json:"heAddressExamples"`
}

type TermNameOptions

type TermNameOptions struct {
	// Number of results to return. 0 indicates no limit.
	Limit int `url:"limit,omitempty" validate:"gte=0" desc:"number of results to return. 0 = no limit."`

	// By default the Name API returns Refs, book titles, authors,
	// topics, and collections. If the type is set, the response will
	// only contain items of that type. Note: Topic includes authors,
	// topics and people without differentiation.
	//
	// If empty, the results will include all types.
	Type string `` /* 147-byte string literal not displayed */
}

type TermService

type TermService service

func (*TermService) Get

func (s *TermService) Get(ctx context.Context, term string) (*Term, error)

Get the given term. A term is a shared title node. It can be referenced and used by many different Index nodes. Terms that use the same TermScheme can be ordered within that scheme. So for example, Parsha terms who all share the TermScheme of parsha, can be ordered within that scheme.

Arguments:

  • term: a valid english name of a sefaria term

Examples of valid terms: Noah, HaChovel

func (*TermService) Name

func (s *TermService) Name(ctx context.Context, name string, opts *TermNameOptions) (*TermCompletions, error)

Name serves primarily as an autocomplete endpoint, returning potential keyword matches for Refs, book titles, authors, topics, and collections available on Sefaria.

Arguments:

  • Name: an arbitrary string to search for matches
  • opts: optional parameters

type TermTitle

type TermTitle struct {
	// The text of the title
	Text bidi.String `json:"text" table:"Title"`

	// The language of the title, either "en" or "he"
	Lang string `json:"lang" table:"Language"`

	// Whether or not the title is a primary title. For any given topics,
	// one should expect two titles with this field present and set to true,
	// an English and a Hebrew primary title. The English value with primary
	// set to true will match the string value of the primaryTitle
	// field on topic.
	Primary bool `json:"primary,omitempty" table:"Primary"`
}

type Text

type Text struct {
	Ref                         string    `json:"ref"`
	HeRef                       string    `json:"heRef"`
	IsComplex                   bool      `json:"isComplex"`
	Text                        []string  `json:"text"`
	He                          []string  `json:"he"`
	Versions                    []Version `json:"versions"`
	TextDepth                   int       `json:"textDepth"`
	SectionNames                []string  `json:"sectionNames"`
	AddressTypes                []string  `json:"addressTypes"`
	Lengths                     []int     `json:"lengths"`
	Length                      int       `json:"length"`
	HeTitle                     string    `json:"heTitle"`
	TitleVariants               []string  `json:"titleVariants"`
	HeTitleVariants             []string  `json:"heTitleVariants"`
	Type                        string    `json:"type"`
	PrimaryCategory             string    `json:"primary_category"`
	Book                        string    `json:"book"`
	Categories                  []string  `json:"categories"`
	Order                       []int     `json:"order"`
	Sections                    []any     `json:"sections"`
	ToSections                  []any     `json:"toSections"`
	Commentator                 string    `json:"commentator"`
	HeCommentator               string    `json:"heCommentator"`
	CollectiveTitle             string    `json:"collectiveTitle"`
	HeCollectiveTitle           string    `json:"heCollectiveTitle"`
	BaseTexTitles               []string  `json:"baseTexTitles"`
	IsDependant                 bool      `json:"isDependant"`
	IndexTitle                  string    `json:"indexTitle"`
	HeIndexTitle                string    `json:"heIndexTitle"`
	SectionRef                  string    `json:"sectionRef"`
	FirstAvailableSectionRef    string    `json:"firstAvailableSectionRef"`
	HeSectionRef                string    `json:"heSectionRef"`
	IsSpanning                  bool      `json:"isSpanning"`
	HeVersionTitle              string    `json:"heVersionTitle"`
	HeVersionTitleInHebrew      string    `json:"heVersionTitleInHebrew"`
	HeShortVersionTitle         string    `json:"heShortVersionTitle"`
	HeShortVersionTitleInHebrew string    `json:"heShortVersionTitleInHebrew"`
	HeVersionSource             string    `json:"heVersionSource"`
	HeVersionStatus             string    `json:"heVersionStatus"`
	HeVersionNotes              string    `json:"heVersionNotes"`
	HeExtendedNotes             string    `json:"heExtendedNotes"`
	HeExtendedNotesHebrew       string    `json:"heExtendedNotesHebrew"`
	HeVersionNotesInHebrew      string    `json:"heVersionNotesInHebrew"`
	HeDigitizedBySefaria        bool      `json:"heDigitizedBySefaria"`
	HeLicense                   string    `json:"heLicense"`
	FormatHeAsPoetry            bool      `json:"formatHeAsPoetry"`
	Title                       string    `json:"title"`
	HeBook                      string    `json:"heBook"`
	Alts                        []any     `json:"alts"`
	IndexOffsetsByDepth         struct{}  `json:"index_offsets_by_depth"`
	Next                        string    `json:"next"`
	Prev                        string    `json:"prev"`
	Commentary                  []any     `json:"commentary"`
	Sheets                      []any     `json:"sheets"`
	Layer                       []any     `json:"layer"`
}

type TextFormat

type TextFormat string
const (
	FormatDefault            TextFormat = "default"
	FormatTextOnly           TextFormat = "text_only"
	FormatStripOnlyFootnotes TextFormat = "strip_only_footnotes"
	FormatWrapAllEntities    TextFormat = "wrap_all_entities"
)

type TextOptions

type TextOptions struct {
	Versions            []TextVersion
	FillMissingSegments bool
	Format              TextFormat
}

func (TextOptions) Query

func (t TextOptions) Query() string

type TextService

type TextService service

func (*TextService) Get

func (s *TextService) Get(ctx context.Context, tref string, opts *TextOptions) (*Text, error)

func (*TextService) Languages

func (s *TextService) Languages(ctx context.Context) ([]string, error)

func (*TextService) Manuscripts

func (s *TextService) Manuscripts(ctx context.Context, tref string) ([]Manuscript, error)

func (*TextService) Random

func (s *TextService) Random(ctx context.Context, opts *RandomTextOptions) (*Text, error)

func (*TextService) Translations

func (s *TextService) Translations(ctx context.Context, lang string) ([]Translation, error)

func (*TextService) Versions

func (s *TextService) Versions(ctx context.Context, index string) ([]Version, error)

type TextVersion

type TextVersion struct {
	Language string
	Title    string
}

func (TextVersion) String

func (t TextVersion) String() string

type Topic

type Topic map[string]any

type TopicService

type TopicService service

func (*TopicService) All

func (s *TopicService) All(ctx context.Context, limit int) ([]Topic, error)

func (*TopicService) Get

func (s *TopicService) Get(ctx context.Context, topic string) (*Topic, error)

func (*TopicService) Graph

func (s *TopicService) Graph(ctx context.Context, topic string, linkType string) ([]Topic, error)

func (*TopicService) Random

func (s *TopicService) Random(ctx context.Context) ([]Topic, error)

func (*TopicService) Recommended

func (s *TopicService) Recommended(ctx context.Context, refs ...string) ([]Topic, error)

type Translation

type Translation struct {
	Category     string `json:"category"`
	Name         string `json:"name"`
	Title        string `json:"title"`
	URL          string `json:"url"`
	VersionTitle string `json:"versionTitle"`
	RTLLanguage  string `json:"rtlLanguage"`
}

type Version

type Version struct {
	Title                     string                  `json:"title"`
	VersionTitle              string                  `json:"versionTitle"`
	VersionSource             string                  `json:"versionSource"`
	Language                  string                  `json:"language"`
	Status                    string                  `json:"status"`
	License                   string                  `json:"license"`
	VersionNotes              string                  `json:"versionNotes"`
	DigitizedBySefaria        types.StringOr[bool]    `json:"digitizedBySefaria"`
	Priority                  types.StringOr[float32] `json:"priority"`
	VersionTitleInHebrew      string                  `json:"versionTitleInHebrew"`
	VersionNotesInHebrew      string                  `json:"versionNotesInHebrew"`
	ExtendedNotes             string                  `json:"extendedNotes"`
	ExtendedNotesHebrew       string                  `json:"extendedNotesHebrew"`
	PurchaseInformationImage  string                  `json:"purchaseInformationImage"`
	PurchaseInformationURL    string                  `json:"purchaseInformationURL"`
	ShortVersionTitle         string                  `json:"shortVersionTitle"`
	ShortVersionTitleInHebrew string                  `json:"shortVersionTitleInHebrew"`
	FirstSectionRef           string                  `json:"firstSectionRef"`

	FormatAsPoetry         string `json:"formatAsPoetry"`
	Method                 string `json:"method"`
	HeversionSource        string `json:"heversionSource"`
	VersionURL             string `json:"versionUrl"`
	HasManuallyWrappedRefs string `json:"hasManuallyWrappedRefs"`
	ActualLanguage         string `json:"actualLanguage"`
	LanguageFamilyName     string `json:"languageFamilyName"`
	IsSource               bool   `json:"isSource"`
	IsPrimary              bool   `json:"isPrimary"`
	Direction              string `json:"direction"`
}

Directories

Path Synopsis
Package bidi provides bidirectional text support for Hebrew and Arabic text.
Package bidi provides bidirectional text support for Hebrew and Arabic text.
Package normalizer provides text normalization utilities for cleaning and standardizing text data.
Package normalizer provides text normalization utilities for cleaning and standardizing text data.
Package types provides custom types with specialized marshaling and unmarshaling behavior for the Sefaria API client.
Package types provides custom types with specialized marshaling and unmarshaling behavior for the Sefaria API client.
Package tz provides timezone detection functionality for cross-platform systems.
Package tz provides timezone detection functionality for cross-platform systems.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL