Skip to content

Commit c6e7d3c

Browse files
add mirascope
1 parent 3a77103 commit c6e7d3c

File tree

3 files changed

+252
-45
lines changed

3 files changed

+252
-45
lines changed

Chapter2/pydantic.ipynb

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -100,23 +100,10 @@
100100
},
101101
{
102102
"cell_type": "code",
103-
"execution_count": 1,
103+
"execution_count": null,
104104
"id": "49c502e7",
105105
"metadata": {},
106-
"outputs": [
107-
{
108-
"ename": "ValidationError",
109-
"evalue": "2 validation errors for Song\nrelease_date\n Input should be less than 2024-05-10 [type=less_than, input_value=datetime.date(2024, 6, 1), input_type=date]\n For further information visit https://errors.pydantic.dev/2.5/v/less_than\nbeats_per_minute\n Field required [type=missing, input_value={'title': 'Believer', 'ar...2024, 6, 1), 'bpm': 125}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.5/v/missing",
110-
"output_type": "error",
111-
"traceback": [
112-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
113-
"\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)",
114-
"Cell \u001b[0;32mIn[1], line 14\u001b[0m\n\u001b[1;32m 10\u001b[0m beats_per_minute: \u001b[38;5;28mint\u001b[39m \u001b[38;5;241m=\u001b[39m Field(multiple_of\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m5\u001b[39m)\n\u001b[1;32m 13\u001b[0m \u001b[38;5;66;03m# Example usage\u001b[39;00m\n\u001b[0;32m---> 14\u001b[0m song1 \u001b[38;5;241m=\u001b[39m \u001b[43mSong\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 15\u001b[0m \u001b[43m \u001b[49m\u001b[43mtitle\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mBeliever\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 16\u001b[0m \u001b[43m \u001b[49m\u001b[43martist\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mImagine Dragons\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 17\u001b[0m \u001b[43m \u001b[49m\u001b[43mduration\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m3.67\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[43mrelease_date\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2024\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m6\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[43mbpm\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m125\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 20\u001b[0m \u001b[43m)\u001b[49m\n",
115-
"File \u001b[0;32m~/book/venv/lib/python3.11/site-packages/pydantic/main.py:164\u001b[0m, in \u001b[0;36mBaseModel.__init__\u001b[0;34m(__pydantic_self__, **data)\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[38;5;66;03m# `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks\u001b[39;00m\n\u001b[1;32m 163\u001b[0m __tracebackhide__ \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[0;32m--> 164\u001b[0m \u001b[43m__pydantic_self__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__pydantic_validator__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalidate_python\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mself_instance\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m__pydantic_self__\u001b[49m\u001b[43m)\u001b[49m\n",
116-
"\u001b[0;31mValidationError\u001b[0m: 2 validation errors for Song\nrelease_date\n Input should be less than 2024-05-10 [type=less_than, input_value=datetime.date(2024, 6, 1), input_type=date]\n For further information visit https://errors.pydantic.dev/2.5/v/less_than\nbeats_per_minute\n Field required [type=missing, input_value={'title': 'Believer', 'ar...2024, 6, 1), 'bpm': 125}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.5/v/missing"
117-
]
118-
}
119-
],
106+
"outputs": [],
120107
"source": [
121108
"from pydantic import BaseModel, Field\n",
122109
"from datetime import date\n",
@@ -125,47 +112,34 @@
125112
"class Song(BaseModel):\n",
126113
" title: str\n",
127114
" artist: str\n",
128-
" duration: float = Field(gt=0.0)\n",
129-
" release_date: date = Field(lt=date.today())\n",
130-
" beats_per_minute: int = Field(multiple_of=5)\n",
115+
" duration: float = Field(gt=0.0) # greater than 0\n",
116+
" release_date: date = Field(lt=date.today()) # before today\n",
117+
" beats_per_minute: int = Field(multiple_of=5) # multiple of 5\n",
131118
"\n",
132119
"\n",
133120
"song1 = Song(\n",
134121
" title=\"Believer\",\n",
135122
" artist=\"Imagine Dragons\",\n",
136-
" duration=3.67,\n",
137-
" release_date=date(2024, 6, 1), \n",
138-
" bpm=125,\n",
123+
" duration=0,\n",
124+
" release_date=date(2024, 6, 1),\n",
125+
" beats_per_minute=125,\n",
139126
")"
140127
]
141128
},
142129
{
143-
"cell_type": "code",
144-
"execution_count": 2,
145-
"id": "d05c1ff0",
130+
"cell_type": "markdown",
131+
"id": "e406a6af",
146132
"metadata": {},
147-
"outputs": [
148-
{
149-
"ename": "ValidationError",
150-
"evalue": "2 validation errors for Song\nduration\n Input should be greater than 0 [type=greater_than, input_value=0, input_type=int]\n For further information visit https://errors.pydantic.dev/2.5/v/greater_than\nbeats_per_minute\n Field required [type=missing, input_value={'title': 'Thunder', 'art...017, 4, 27), 'bpm': 165}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.5/v/missing",
151-
"output_type": "error",
152-
"traceback": [
153-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
154-
"\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)",
155-
"Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m song2 \u001b[38;5;241m=\u001b[39m \u001b[43mSong\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mtitle\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mThunder\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43martist\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mImagine Dragons\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[43mduration\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[43mrelease_date\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2017\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m4\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m27\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 6\u001b[0m \u001b[43m \u001b[49m\u001b[43mbpm\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m165\u001b[39;49m\n\u001b[1;32m 7\u001b[0m \u001b[43m)\u001b[49m\n",
156-
"File \u001b[0;32m~/book/venv/lib/python3.11/site-packages/pydantic/main.py:164\u001b[0m, in \u001b[0;36mBaseModel.__init__\u001b[0;34m(__pydantic_self__, **data)\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[38;5;66;03m# `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks\u001b[39;00m\n\u001b[1;32m 163\u001b[0m __tracebackhide__ \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[0;32m--> 164\u001b[0m \u001b[43m__pydantic_self__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__pydantic_validator__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalidate_python\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mself_instance\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m__pydantic_self__\u001b[49m\u001b[43m)\u001b[49m\n",
157-
"\u001b[0;31mValidationError\u001b[0m: 2 validation errors for Song\nduration\n Input should be greater than 0 [type=greater_than, input_value=0, input_type=int]\n For further information visit https://errors.pydantic.dev/2.5/v/greater_than\nbeats_per_minute\n Field required [type=missing, input_value={'title': 'Thunder', 'art...017, 4, 27), 'bpm': 165}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.5/v/missing"
158-
]
159-
}
160-
],
161133
"source": [
162-
"song2 = Song(\n",
163-
" title=\"Thunder\",\n",
164-
" artist=\"Imagine Dragons\",\n",
165-
" duration=0,\n",
166-
" release_date=date(2017, 4, 27),\n",
167-
" bpm=165\n",
168-
")"
134+
"```bash\n",
135+
"ValidationError: 2 validation errors for Song\n",
136+
"duration\n",
137+
" Input should be greater than 0 [type=greater_than, input_value=0, input_type=int]\n",
138+
" For further information visit https://errors.pydantic.dev/2.5/v/greater_than\n",
139+
"release_date\n",
140+
" Input should be less than 2024-05-10 [type=less_than, input_value=datetime.date(2024, 6, 1), input_type=date]\n",
141+
" For further information visit https://errors.pydantic.dev/2.5/v/less_than\n",
142+
"```"
169143
]
170144
},
171145
{

Chapter5/better_pandas.ipynb

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,6 +3605,77 @@
36053605
"source": [
36063606
"[Link to polars](https://github.com/pola-rs/polars)"
36073607
]
3608+
},
3609+
{
3610+
"cell_type": "markdown",
3611+
"id": "08d428a1",
3612+
"metadata": {},
3613+
"source": [
3614+
"### Polars' Streaming Mode: A Solution for Large Data Sets"
3615+
]
3616+
},
3617+
{
3618+
"cell_type": "code",
3619+
"execution_count": null,
3620+
"id": "84f445b0",
3621+
"metadata": {
3622+
"tags": [
3623+
"hide-cell"
3624+
]
3625+
},
3626+
"outputs": [],
3627+
"source": [
3628+
"!pip install polars"
3629+
]
3630+
},
3631+
{
3632+
"cell_type": "code",
3633+
"execution_count": null,
3634+
"id": "db64cab3",
3635+
"metadata": {
3636+
"tags": [
3637+
"remove-cell"
3638+
]
3639+
},
3640+
"outputs": [],
3641+
"source": [
3642+
"!wget https://raw.githubusercontent.com/pola-rs/polars/main/docs/data/reddit.csv "
3643+
]
3644+
},
3645+
{
3646+
"cell_type": "markdown",
3647+
"id": "d0ba1f75",
3648+
"metadata": {},
3649+
"source": [
3650+
"The default collect method in Polars processes your data as a single batch, which means that all the data must fit into your available memory.\n",
3651+
"\n",
3652+
"If your data requires more memory than you have available, Polars can process it in batches using streaming mode. To use streaming mode, simply pass the `streaming=True` argument to the `collect` method."
3653+
]
3654+
},
3655+
{
3656+
"cell_type": "code",
3657+
"execution_count": 4,
3658+
"id": "a9eb07c8",
3659+
"metadata": {},
3660+
"outputs": [],
3661+
"source": [
3662+
"import polars as pl\n",
3663+
"\n",
3664+
"df = (\n",
3665+
" pl.scan_csv(\"reddit.csv\")\n",
3666+
" .with_columns(pl.col(\"name\").str.to_uppercase())\n",
3667+
" .filter(pl.col(\"comment_karma\") > 0)\n",
3668+
" .collect(streaming=True)\n",
3669+
")"
3670+
]
3671+
},
3672+
{
3673+
"cell_type": "markdown",
3674+
"id": "7ddfa843",
3675+
"metadata": {},
3676+
"source": [
3677+
"[Learn more about Streaming API in Polars](https://bit.ly/3wlTZXR)."
3678+
]
36083679
}
36093680
],
36103681
"metadata": {

Chapter5/llm.ipynb

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,168 @@
343343
"source": [
344344
"[Link to Mirascope](https://bit.ly/4bkciv3)."
345345
]
346+
},
347+
{
348+
"cell_type": "markdown",
349+
"id": "e6bc77a1",
350+
"metadata": {},
351+
"source": [
352+
"### Maximize Accuracy and Relevance with External Data and LLMs"
353+
]
354+
},
355+
{
356+
"cell_type": "code",
357+
"execution_count": null,
358+
"id": "1518900b",
359+
"metadata": {
360+
"tags": [
361+
"hide-cell"
362+
]
363+
},
364+
"outputs": [],
365+
"source": [
366+
"!pip install -U mirascope"
367+
]
368+
},
369+
{
370+
"cell_type": "markdown",
371+
"id": "eb5be483",
372+
"metadata": {},
373+
"source": [
374+
"Combining external data and an LLM offers the best of both worlds: accuracy and relevance. External data provides up-to-date information, while an LLM can generate text based on input prompts. Together, they enable a system to respond helpfully to a wider range of queries.\n",
375+
"\n",
376+
"Mirascope simplifies this combination with Pythonic code. In the example below, we use an LLM to process natural language prompts and query the database for data."
377+
]
378+
},
379+
{
380+
"cell_type": "code",
381+
"execution_count": 117,
382+
"id": "620f3cf4",
383+
"metadata": {
384+
"tags": [
385+
"hide-cell"
386+
]
387+
},
388+
"outputs": [
389+
{
390+
"name": "stdout",
391+
"output_type": "stream",
392+
"text": [
393+
"Database created with sample data.\n"
394+
]
395+
}
396+
],
397+
"source": [
398+
"import sqlite3\n",
399+
"\n",
400+
"# Connect to the database (or create it if it doesn't exist)\n",
401+
"conn = sqlite3.connect(\"grocery.db\")\n",
402+
"cursor = conn.cursor()\n",
403+
"\n",
404+
"# Create the 'grocery_items' table\n",
405+
"cursor.execute(\n",
406+
" \"\"\"\n",
407+
" CREATE TABLE IF NOT EXISTS grocery_items (\n",
408+
" id INTEGER PRIMARY KEY AUTOINCREMENT,\n",
409+
" name TEXT NOT NULL,\n",
410+
" category TEXT NOT NULL,\n",
411+
" price REAL NOT NULL\n",
412+
" )\n",
413+
"\"\"\"\n",
414+
")\n",
415+
"\n",
416+
"# Insert some sample data\n",
417+
"items = [\n",
418+
" (\"apple\", \"Fruits\", 0.75),\n",
419+
" (\"banana\", \"Fruits\", 0.50),\n",
420+
" (\"carrot\", \"Vegetables\", 1.20),\n",
421+
"]\n",
422+
"\n",
423+
"cursor.executemany(\n",
424+
" \"INSERT INTO grocery_items (name, category, price) VALUES (?, ?, ?)\", items\n",
425+
")\n",
426+
"\n",
427+
"# Commit the changes and close the connection\n",
428+
"conn.commit()\n",
429+
"conn.close()\n",
430+
"print(\"Database created with sample data.\")"
431+
]
432+
},
433+
{
434+
"cell_type": "code",
435+
"execution_count": 6,
436+
"id": "fd431ee6",
437+
"metadata": {},
438+
"outputs": [],
439+
"source": [
440+
"import os\n",
441+
"\n",
442+
"\n",
443+
"os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n"
444+
]
445+
},
446+
{
447+
"cell_type": "code",
448+
"execution_count": 129,
449+
"id": "da316438",
450+
"metadata": {},
451+
"outputs": [
452+
{
453+
"data": {
454+
"text/plain": [
455+
"'The price for apple is 0.75.'"
456+
]
457+
},
458+
"execution_count": 129,
459+
"metadata": {},
460+
"output_type": "execute_result"
461+
}
462+
],
463+
"source": [
464+
"from mirascope.openai import OpenAICall, OpenAICallParams\n",
465+
"import sqlite3\n",
466+
"\n",
467+
"# Assume you have a SQLite database with a 'grocery_items' table\n",
468+
"conn = sqlite3.connect(\"grocery.db\")\n",
469+
"\n",
470+
"\n",
471+
"def get_item_info(table_name: str, item_name: str, info: str) -> dict:\n",
472+
" \"\"\"Get `info` from the `table_name` database table based on `name`.\"\"\"\n",
473+
" cursor = conn.cursor()\n",
474+
" try:\n",
475+
" row = cursor.execute(\n",
476+
" f\"SELECT {info} FROM {table_name} WHERE name = ?\", (item_name,)\n",
477+
" ).fetchone()\n",
478+
" return f\"The {info} for {item_name} is {row[0]}.\"\n",
479+
" except TypeError:\n",
480+
" return f\"Sorry but {item_name} doesn't exist in the database.\"\n",
481+
"\n",
482+
"\n",
483+
"class GroceryItemQuery(OpenAICall):\n",
484+
" prompt_template = \"\"\"\n",
485+
" SYSTEM:\n",
486+
" Your task is properly query a database given a user's input.\n",
487+
"\n",
488+
" USER:\n",
489+
" {input}\n",
490+
" \"\"\"\n",
491+
" input: str\n",
492+
" call_params = OpenAICallParams(tools=[get_item_info])\n",
493+
"\n",
494+
"\n",
495+
"text = \"What's the price for apple in the grocery_items table?\"\n",
496+
"query_tool = GroceryItemQuery(input=text).call().tool\n",
497+
"result = query_tool.fn(**query_tool.args)\n",
498+
"result"
499+
]
500+
},
501+
{
502+
"cell_type": "markdown",
503+
"id": "ff418e55",
504+
"metadata": {},
505+
"source": [
506+
"[Link to Mirascope](https://bit.ly/4awfNhg)."
507+
]
346508
}
347509
],
348510
"metadata": {

0 commit comments

Comments
 (0)