[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"readme:fenic":3},"\n\u003Cdiv align=\"center\">\n    \u003Cpicture>\n        \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs\u002Fimages\u002Ftypedef-fenic-logo-dark.png\">\u003C\u002Fsource>\n        \u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002Ftypedef-ai\u002Ffenic\u002FHEAD\u002Fdocs\u002Fimages\u002Ftypedef-fenic-logo-github-yellow.png\" alt=\"fenic, by typedef\" width=\"90%\" \u002F>\n    \u003C\u002Fpicture>\n\u003C\u002Fdiv>\u003Ch1>fenic: semantic DataFrames for humans and agents\u003C\u002Fh1>\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Ffenic\u002F\" rel=\"nofollow ugc noopener\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Ffenic.svg\" alt=\"PyPI version\" \u002F>\u003C\u002Fa>\n\u003Ca href=\"https:\u002F\u002Fpypi.org\u002Fproject\u002Ffenic\u002F\" rel=\"nofollow ugc noopener\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fpyversions\u002Ffenic.svg\" alt=\"Python versions\" \u002F>\u003C\u002Fa>\n\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Ftypedef-ai\u002Ffenic\u002Fblob\u002Fmain\u002FLICENSE\" rel=\"nofollow ugc noopener\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002Ftypedef-ai\u002Ffenic.svg\" alt=\"License\" \u002F>\u003C\u002Fa>\n\u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002FGdqF3J7huR\" rel=\"nofollow ugc noopener\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F1381706122322513952?label=Discord&amp;logo=discord\" alt=\"Discord\" \u002F>\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>\u003Cstrong>fenic turns AI-assisted exploration of structured and unstructured data into reusable, inspectable DataFrame pipelines.\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>It's a DataFrame query engine for semantic data processing, with AI operators — \u003Ccode>extract\u003C\u002Fcode>, \u003Ccode>classify\u003C\u002Fcode>, \u003Ccode>summarize\u003C\u002Fcode>, \u003Ccode>embed\u003C\u002Fcode>, semantic \u003Ccode>join\u003C\u002Fcode>, and more — built into the query model. Use it to turn documents, transcripts, logs, eval traces, tickets, tables, and APIs into typed rows and repeatable workflows.\u003C\u002Fp>\n\u003Cp>The point is a shift in what your data work \u003Cem>produces\u003C\u002Fem>. Humans and agents work on the same pipelines — both can author, inspect, and reuse them. The result isn't a one-off prompt or a brittle regex script that has to be reverse-engineered later — it's a durable artifact: typed, inspectable, rerunnable, and callable.\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>From exploration to artifact.\u003C\u002Fstrong>\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cpre>\u003Ccode class=\"language-bash\">pip install fenic\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Writing fenic with an AI coding agent?\u003C\u002Fstrong> Run \u003Ccode>fenic skill install\u003C\u002Fcode> so Claude Code \u002F Cursor \u002F Codex write it correctly, and \u003Ccode>fenic check\u003C\u002Fcode> to lint it — \u003Ca href=\"#writing-fenic-with-an-ai-coding-agent\" rel=\"nofollow ugc noopener\">details below\u003C\u002Fa>.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Chr \u002F>\n\u003Ch2>What is fenic?\u003C\u002Fh2>\n\u003Cp>fenic is a \u003Cstrong>semantic DataFrame engine\u003C\u002Fstrong>. You write the PySpark\u002FSQL-style operations you already know — \u003Ccode>select\u003C\u002Fcode>, \u003Ccode>filter\u003C\u002Fcode>, \u003Ccode>join\u003C\u002Fcode>, \u003Ccode>group_by\u003C\u002Fcode>, \u003Ccode>agg\u003C\u002Fcode> — alongside \u003Cem>semantic operators\u003C\u002Fem> that call language models as a first-class part of the query. You configure models once on a \u003Ccode>Session\u003C\u002Fcode>, build a pipeline lazily, and fenic compiles and runs it on a query engine built for inference: automatic batching, rate limiting, retries, token\u002Fcost accounting, and response caching.\u003C\u002Fp>\n\u003Cp>Two ideas make it different from gluing an LLM onto pandas:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Inference lives inside the query model.\u003C\u002Fstrong> Extraction, classification, summarization, and embeddings are operators with schemas and types — not side calls you orchestrate by hand.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The pipeline is the artifact.\u003C\u002Fstrong> Because the work is expressed as typed operators, it's already inspectable (row-level lineage, \u003Ccode>explain\u003C\u002Fcode>, per-query metrics), rerunnable (lazy plans + caching), and promotable into a named table, view, or \u003Cstrong>MCP tool\u003C\u002Fstrong> an agent can call.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr \u002F>\n\u003Ch2>60 seconds: messy text → typed rows\u003C\u002Fh2>\n\u003Cp>Replace brittle parsing and one-off prompts with a typed, schema-bound operator. Define the shape you want as a Pydantic model; fenic returns structured columns you can query.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-python\">import fenic as fc\nfrom pydantic import BaseModel, Field\n\nclass Ticket(BaseModel):\n    product: str = Field(description=\"The product the user is asking about\")\n    sentiment: str = Field(description=\"positive, neutral, or negative\")\n    issue: str = Field(description=\"One-line summary of the user's problem\")\n\nsession = fc.Session.get_or_create(\n    fc.SessionConfig(\n        app_name=\"quickstart\",\n        semantic=fc.SemanticConfig(\n            language_models={\n                \"mini\": fc.OpenAILanguageModel(model_name=\"gpt-4o-mini\", rpm=500, tpm=200_000)\n            },\n        ),\n    )\n)\n\ndf = session.create_dataframe([\n    {\"id\": 1, \"text\": \"The CSV export in Reports keeps timing out since the last update.\"},\n    {\"id\": 2, \"text\": \"Love the new dashboard, but SSO login is broken on mobile.\"},\n])\n\n# Free text -&gt; typed, queryable rows\ntickets = (\n    df.select(\"id\", fc.semantic.extract(\"text\", Ticket).\n\u003C\u002Fcode>\u003C\u002Fpre>\n",1787530083524]