From 6b01d0a65f3e59b3aa72fe7b1d74f804171d7f7d Mon Sep 17 00:00:00 2001 From: Cameron Bates Date: Thu, 31 Jul 2025 14:56:00 -0400 Subject: [PATCH 1/3] Make Langcache SDK python and javascript TCE files and add footer argument to hide footer --- content/develop/ai/langcache/api-examples.md | 130 +++---------------- layouts/partials/tabbed-clients-example.html | 3 +- layouts/shortcodes/clients-example.html | 5 + local_examples/langcache/langcache_sdk.js | 94 ++++++++++++++ local_examples/langcache/langcache_sdk.py | 63 +++++++++ 5 files changed, 180 insertions(+), 115 deletions(-) create mode 100644 local_examples/langcache/langcache_sdk.js create mode 100644 local_examples/langcache/langcache_sdk.py diff --git a/content/develop/ai/langcache/api-examples.md b/content/develop/ai/langcache/api-examples.md index 18d3e0e04..be5ab5970 100644 --- a/content/develop/ai/langcache/api-examples.md +++ b/content/develop/ai/langcache/api-examples.md @@ -11,7 +11,12 @@ title: Use the LangCache API and SDK weight: 10 --- -Use the LangCache API from your client app to store and retrieve LLM, RAG, or agent responses. +Use the [LangCache API]({{< relref "/develop/ai/langcache/api-reference" >}}) from your client app to store and retrieve LLM, RAG, or agent responses. + +You can use any standard REST client or library to access the API. If your app is written in Python or Javascript, you can also use the LangCache Software Development Kits (SDKs) to access the API: + +- [LangCache SDK for Python](https://pypi.org/project/langcache/) +- [LangCache SDK for Javascript](https://www.npmjs.com/package/@redis-ai/langcache) To access the LangCache API, you need: @@ -19,16 +24,16 @@ To access the LangCache API, you need: - LangCache service API key - Cache ID -When you call the API, you need to pass the LangCache API key in the `Authorization` header as a Bearer token and the Cache ID as the `cacheId` path parameter. +When you call the API, you need to pass the LangCache API key in the `Authorization` header as a Bearer token and the Cache ID as the `cacheId` path parameter. -For example, to search the cache using `cURL`: +For example: -```bash -curl -s -X POST "https://$HOST/v1/caches/$CACHE_ID/entires/search" \ +{{< clients-example set="langcache_sdk" step="imports_setup" dft_tab_name="cURL" footer="hide" >}} +curl -s -X POST "https://$HOST/v1/caches/$CACHE_ID/entries/search" \ -H "accept: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d "{ 'prompt': 'What is semantic caching' }" -``` +{{< /clients-example >}} - The example expects several variables to be set in the shell: @@ -36,72 +41,18 @@ curl -s -X POST "https://$HOST/v1/caches/$CACHE_ID/entires/search" \ - **$CACHE_ID** - the Cache ID of your cache - **$API_KEY** - The LangCache API token -{{% info %}} -This example uses `cURL` and Linux shell scripts to demonstrate the API; you can use any standard REST client or library. -{{% /info %}} - -If your app is written in Python or Javascript, you can also use the LangCache Software Development Kits (SDKs) to access the API: - -- [LangCache SDK for Python](https://pypi.org/project/langcache/) -- [LangCache SDK for Javascript](https://www.npmjs.com/package/@redis-ai/langcache) - ## Examples ### Search LangCache for similar responses -Use [`POST /v1/caches/{cacheId}/entries/search`]({{< relref "/develop/ai/langcache/api-reference#tag/Cache-Entries/operation/search" >}}}) to search the cache for matching responses to a user prompt. +Use [`POST /v1/caches/{cacheId}/entries/search`]({{< relref "/develop/ai/langcache/api-reference#tag/Cache-Entries/operation/search" >}}) to search the cache for matching responses to a user prompt. -{{< multitabs id="search-basic" - tab1="REST API" - tab2="Python" - tab3="Javascript" >}} -```sh +{{< clients-example set="langcache_sdk" step="search_basic" dft_tab_name="REST API" footer="hide" >}} POST https://[host]/v1/caches/{cacheId}/entries/search { "prompt": "User prompt text" } -``` --tab-sep- -```python -from langcache import LangCache -import os - - -with LangCache( - server_url="https://", - cache_id="", - service_key=os.getenv("LANGCACHE_SERVICE_KEY", ""), -) as lang_cache: - - res = lang_cache.search( - prompt="User prompt text", - similarity_threshold=0.9 - ) - - print(res) -``` --tab-sep- -```js -import { LangCache } from "@redis-ai/langcache"; - -const langCache = new LangCache({ - serverURL: "https://", - cacheId: "", - serviceKey: "", -}); - -async function run() { - const result = await langCache.search({ - prompt: "User prompt text", - similarityThreshold: 0.9 - }); - - console.log(result); -} - -run(); -``` -{{< /multitabs >}} +{{< /clients-example >}} Place this call in your client app right before you call your LLM's REST API. If LangCache returns a response, you can send that response back to the user instead of calling the LLM. @@ -109,11 +60,7 @@ If LangCache does not return a response, you should call your LLM's REST API to You can also scope the responses returned from LangCache by adding an `attributes` object to the request. LangCache will only return responses that match the attributes you specify. -{{< multitabs id="search-attributes" - tab1="REST API" - tab2="Python" - tab3="Javascript" >}} -```sh +{{< clients-example set="langcache_sdk" step="search_attributes" dft_tab_name="REST API" footer="hide" >}} POST https://[host]/v1/caches/{cacheId}/entries/search { "prompt": "User prompt text", @@ -121,52 +68,7 @@ POST https://[host]/v1/caches/{cacheId}/entries/search "customAttributeName": "customAttributeValue" } } -``` --tab-sep- -```python -from langcache import LangCache -import os - - -with LangCache( - server_url="https://", - cache_id="", - service_key=os.getenv("LANGCACHE_SERVICE_KEY", ""), -) as lang_cache: - - res = lang_cache.search( - prompt="User prompt text", - attributes={"customAttributeName": "customAttributeValue"}, - similarity_threshold=0.9, - ) - - print(res) -``` --tab-sep- -```js -import { LangCache } from "@redis-ai/langcache"; - -const langCache = new LangCache({ - serverURL: "https://", - cacheId: "", - serviceKey: "", -}); - -async function run() { - const result = await langCache.search({ - prompt: "User prompt text", - similarityThreshold: 0.9, - attributes: { - "customAttributeName": "customAttributeValue", - }, - }); - - console.log(result); -} - -run(); -``` -{{< /multitabs >}} +{{< /clients-example >}} ### Store a new response in LangCache diff --git a/layouts/partials/tabbed-clients-example.html b/layouts/partials/tabbed-clients-example.html index dda5df4a2..c83a44f4b 100644 --- a/layouts/partials/tabbed-clients-example.html +++ b/layouts/partials/tabbed-clients-example.html @@ -6,6 +6,7 @@ {{ $cliTabName := (or (.Scratch.Get "cli_tab_name") ">_ Redis CLI") }} {{ $cliFooterLinkText := .Scratch.Get "cli_footer_link_text" }} {{ $cliFooterLinkUrl := .Scratch.Get "cli_footer_link_url" }} +{{ $showFooter := .Scratch.Get "show_footer" | default true }} {{ if not (isset $.Site.Data.examples $id) }} {{ warnf "[tabbed-clients-example] Example not found %q for %q" $id $.Page }} @@ -51,5 +52,5 @@ {{ end }} {{ end }} -{{ $params := dict "id" (printf "%s-step%s" $id $step) "tabs" $tabs "showFooter" true }} +{{ $params := dict "id" (printf "%s-step%s" $id $step) "tabs" $tabs "showFooter" $showFooter }} {{ partial "tabs/wrapper.html" $params }} diff --git a/layouts/shortcodes/clients-example.html b/layouts/shortcodes/clients-example.html index 22203ae0a..7b4c64ac0 100644 --- a/layouts/shortcodes/clients-example.html +++ b/layouts/shortcodes/clients-example.html @@ -9,6 +9,7 @@ - dft_tab_name: Custom first tab name (optional, default: ">_ Redis CLI") - dft_tab_link_title: Custom first tab footer link title (optional) - dft_tab_url: Custom first tab footer link URL (optional) + - show_footer: Show footer (optional, default: true) Positional parameters (for backward compatibility): - 0: example set name @@ -25,6 +26,7 @@ {{ if .Get "set" }} {{ $usingNamedParams = true }} {{ end }} +{{ .Scratch.Set "show_footer" true }} {{/* Set parameters based on whether we're using named or positional */}} {{ if $usingNamedParams }} @@ -36,6 +38,9 @@ {{ .Scratch.Set "cli_tab_name" (.Get "dft_tab_name") }} {{ .Scratch.Set "cli_footer_link_text" (.Get "dft_tab_link_title") }} {{ .Scratch.Set "cli_footer_link_url" (.Get "dft_tab_url") }} + {{ if eq (.Get "footer") "hide" }} + {{ .Scratch.Set "show_footer" false }} + {{ end }} {{ else }} {{/* Positional parameters (backward compatibility) */}} {{ .Scratch.Set "example" (.Get 0) }} diff --git a/local_examples/langcache/langcache_sdk.js b/local_examples/langcache/langcache_sdk.js new file mode 100644 index 000000000..533759a9b --- /dev/null +++ b/local_examples/langcache/langcache_sdk.js @@ -0,0 +1,94 @@ +// EXAMPLE: langcache_sdk +// STEP_START imports_setup +import { LangCache } from "@redis-ai/langcache"; + +const langCache = new LangCache({ + serverURL: "https://" + process.env.HOST, + cacheId: process.env.CACHE_ID, + serviceKey: process.env.API_KEY, + }); +// STEP_END + +// STEP_START search_basic +async function searchBasic() { + const result = await langCache.search({ + prompt: "User prompt text", + similarityThreshold: 0.9, + }); + + console.log(result); +} + +searchBasic(); +// STEP_END + +// STEP_START search_attributes +async function searchAttributes() { + const result = await langCache.search({ + prompt: "User prompt text", + attributes: { + "customAttributeName": "customAttributeValue", + }, + similarityThreshold: 0.9, + }); + + console.log(result); +} + +searchAttributes(); +// STEP_END + +// STEP_START store_basic +async function storeBasic() { + const result = await langCache.set({ + prompt: "User prompt text", + response: "LLM response text", + }); + + console.log(result); +} + +storeBasic(); +// STEP_END + +// STEP_START store_attributes +async function storeAttributes() { + const result = await langCache.set({ + prompt: "User prompt text", + response: "LLM response text", + attributes: { + "customAttributeName": "customAttributeValue", + }, + }); + + console.log(result); +} + +storeAttributes(); +// STEP_END + +// STEP_START delete_entry +async function deleteEntry() { + const result = await langCache.deleteById({ + entryId: "", + }); + + console.log(result); +} + +deleteEntry(); +// STEP_END + +// STEP_START delete_query +async function deleteQuery() { + const result = await langCache.deleteQuery({ + attributes: { + "customAttributeName": "customAttributeValue", + }, + }); + + console.log(result); +} + +deleteQuery(); +// STEP_END \ No newline at end of file diff --git a/local_examples/langcache/langcache_sdk.py b/local_examples/langcache/langcache_sdk.py new file mode 100644 index 000000000..ef36a71e0 --- /dev/null +++ b/local_examples/langcache/langcache_sdk.py @@ -0,0 +1,63 @@ +# EXAMPLE: langcache_sdk +# STEP_START imports_setup +from langcache import LangCache +import os + +lang_cache = LangCache( + server_url=f"https://{os.getenv('HOST', '')}", + cache_id=os.getenv("CACHE_ID", ""), + service_key=os.getenv("API_KEY", "") +) +# STEP_END + +# STEP_START search_basic +res = lang_cache.search( + prompt="User prompt text", + similarity_threshold=0.9 +) + +print(res) +# STEP_END + +# STEP_START search_attributes +res = lang_cache.search( + prompt="User prompt text", + attributes={"customAttributeName": "customAttributeValue"}, + similarity_threshold=0.9, +) + +print(res) +# STEP_END + +# STEP_START store_basic +res = lang_cache.set( + prompt="User prompt text", + response="LLM response text", +) + +print(res) +# STEP_END + +# STEP_START store_attributes +res = lang_cache.set( + prompt="User prompt text", + response="LLM response text", + attributes={"customAttributeName": "customAttributeValue"}, +) + +print(res) +# STEP_END + +# STEP_START delete_entry +res = lang_cache.delete_by_id(entry_id="") + +print(res) +# STEP_END + +# STEP_START delete_query +res = lang_cache.delete_query( + attributes={"customAttributeName": "customAttributeValue"}, +) + +print(res) +# STEP_END From 34c2167595b8570a042464c7bf1bbcadf5d9c834 Mon Sep 17 00:00:00 2001 From: Cameron Bates Date: Thu, 31 Jul 2025 15:03:55 -0400 Subject: [PATCH 2/3] Swap to client examples for all examples --- content/develop/ai/langcache/api-examples.md | 220 +------------------ 1 file changed, 9 insertions(+), 211 deletions(-) diff --git a/content/develop/ai/langcache/api-examples.md b/content/develop/ai/langcache/api-examples.md index be5ab5970..927bfe279 100644 --- a/content/develop/ai/langcache/api-examples.md +++ b/content/develop/ai/langcache/api-examples.md @@ -35,7 +35,7 @@ curl -s -X POST "https://$HOST/v1/caches/$CACHE_ID/entries/search" \ -d "{ 'prompt': 'What is semantic caching' }" {{< /clients-example >}} -- The example expects several variables to be set in the shell: +This example expects several variables to be set in the shell: - **$HOST** - the LangCache API base URL - **$CACHE_ID** - the Cache ID of your cache @@ -74,75 +74,19 @@ POST https://[host]/v1/caches/{cacheId}/entries/search Use [`POST /v1/caches/{cacheId}/entries`]({{< relref "/develop/ai/langcache/api-reference#tag/Cache-Entries/operation/set" >}}) to store a new response in the cache. -{{< multitabs id="store-basic" - tab1="REST API" - tab2="Python" - tab3="Javascript" >}} - -```sh +{{< clients-example set="langcache_sdk" step="store_basic" dft_tab_name="REST API" footer="hide" >}} POST https://[host]/v1/caches/{cacheId}/entries { "prompt": "User prompt text", "response": "LLM response text" } -``` - --tab-sep- - -```python -from langcache import LangCache -import os - - -with LangCache( - server_url="https://[host]", - cache_id="{cacheId}", - service_key=os.getenv("LANGCACHE_SERVICE_KEY", ""), -) as lang_cache: - - res = lang_cache.set( - prompt="User prompt text", - response="LLM response text", - ) - - print(res) -``` - --tab-sep- - -```js -import { LangCache } from "@redis-ai/langcache"; - -const langCache = new LangCache({ - serverURL: "https://", - cacheId: "", - serviceKey: "", -}); - -async function run() { - const result = await langCache.set({ - prompt: "User prompt text", - response: "LLM response text", - }); - - console.log(result); -} - -run(); -``` - -{{< /multitabs >}} +{{< /clients-example >}} Place this call in your client app after you get a response from the LLM. This will store the response in the cache for future use. You can also store the responses with custom attributes by adding an `attributes` object to the request. -{{< multitabs id="store-attributes" - tab1="REST API" - tab2="Python" - tab3="Javascript" >}} - -```sh +{{< clients-example set="langcache_sdk" step="store_attributes" dft_tab_name="REST API" footer="hide" >}} POST https://[host]/v1/caches/{cacheId}/entries { "prompt": "User prompt text", @@ -151,110 +95,15 @@ POST https://[host]/v1/caches/{cacheId}/entries "customAttributeName": "customAttributeValue" } } -``` --tab-sep- - -```python -from langcache import LangCache -import os - - -with LangCache( - server_url="https://[host]", - cache_id="{cacheId}", - service_key=os.getenv("LANGCACHE_SERVICE_KEY", ""), -) as lang_cache: - - res = lang_cache.set( - prompt="User prompt text", - response="LLM response text", - attributes={"customAttributeName": "customAttributeValue"}, - ) - - print(res) -``` - --tab-sep- - -```js -import { LangCache } from "@redis-ai/langcache"; - -const langCache = new LangCache({ - serverURL: "https://", - cacheId: "", - serviceKey: "", -}); - -async function run() { - const result = await langCache.set({ - prompt: "User prompt text", - response: "LLM response text", - attributes: { - "customAttributeName": "customAttributeValue", - }, - }); - - console.log(result); -} - -run(); -``` - -{{< /multitabs >}} +{{< /clients-example >}} ### Delete cached responses Use [`DELETE /v1/caches/{cacheId}/entries/{entryId}`]({{< relref "/develop/ai/langcache/api-reference#tag/Cache-Entries/operation/delete" >}}) to delete a cached response from the cache. -{{< multitabs id="delete-entry" - tab1="REST API" - tab2="Python" - tab3="Javascript" >}} - -```sh +{{< clients-example set="langcache_sdk" step="delete_entry" dft_tab_name="REST API" footer="hide" >}} DELETE https://[host]/v1/caches/{cacheId}/entries/{entryId} -``` --tab-sep- - -```python -from langcache import LangCache -import os - - -with LangCache( - server_url="https://[host]", - cache_id="{cacheId}", - service_key=os.getenv("LANGCACHE_SERVICE_KEY", ""), -) as lang_cache: - - res = lang_cache.delete_by_id(entry_id="{entryId}") - - print(res) -``` - --tab-sep- - -```js -import { LangCache } from "@redis-ai/langcache"; - -const langCache = new LangCache({ - serverURL: "https://", - cacheId: "", - serviceKey: "", -}); - -async function run() { - const result = await langCache.deleteById({ - entryId: "", - }); - - console.log(result); -} - -run(); -``` - -{{< /multitabs >}} +{{< /clients-example >}} You can also use [`DELETE /v1/caches/{cacheId}/entries`]({{< relref "/develop/ai/langcache/api-reference#tag/Cache-Entries/operation/deleteQuery" >}}) to delete multiple cached responses based on the `attributes` you specify. If you specify multiple `attributes`, LangCache will delete entries that contain all given attributes. @@ -264,63 +113,12 @@ If you do not specify any `attributes`, all responses in the cache will be delet
-{{< multitabs id="delete-attributes" - tab1="REST API" - tab2="Python" - tab3="Javascript" >}} - -```sh +{{< clients-example set="langcache_sdk" step="delete_query" dft_tab_name="REST API" footer="hide" >}} DELETE https://[host]/v1/caches/{cacheId}/entries { "attributes": { "customAttributeName": "customAttributeValue" } } -``` - --tab-sep- - -```python -from langcache import LangCache -import os - - -with LangCache( - server_url="https://[host]", - cache_id="{cacheId}", - service_key=os.getenv("LANGCACHE_SERVICE_KEY", ""), -) as lang_cache: - - res = lang_cache.delete_query( - attributes={"customAttributeName": "customAttributeValue"}, - ) - - print(res) -``` - --tab-sep- - -```js -import { LangCache } from "@redis-ai/langcache"; - -const langCache = new LangCache({ - serverURL: "https://", - cacheId: "", - serviceKey: "", -}); - -async function run() { - const result = await langCache.deleteQuery({ - attributes: { - "customAttributeName": "customAttributeValue", - }, - }); - - console.log(result); -} - -run(); -``` - -{{< /multitabs >}} +{{< /clients-example >}} From 19da3fdd6af651a83d847a399c85c5e5a56f901d Mon Sep 17 00:00:00 2001 From: Cameron Bates Date: Thu, 31 Jul 2025 15:11:49 -0400 Subject: [PATCH 3/3] formatting error and adding auth section --- content/develop/ai/langcache/api-examples.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/content/develop/ai/langcache/api-examples.md b/content/develop/ai/langcache/api-examples.md index 927bfe279..b93dbf10f 100644 --- a/content/develop/ai/langcache/api-examples.md +++ b/content/develop/ai/langcache/api-examples.md @@ -18,6 +18,8 @@ You can use any standard REST client or library to access the API. If your app i - [LangCache SDK for Python](https://pypi.org/project/langcache/) - [LangCache SDK for Javascript](https://www.npmjs.com/package/@redis-ai/langcache) +## Authentication + To access the LangCache API, you need: - LangCache API base URL @@ -37,9 +39,9 @@ curl -s -X POST "https://$HOST/v1/caches/$CACHE_ID/entries/search" \ This example expects several variables to be set in the shell: - - **$HOST** - the LangCache API base URL - - **$CACHE_ID** - the Cache ID of your cache - - **$API_KEY** - The LangCache API token +- **$HOST** - the LangCache API base URL +- **$CACHE_ID** - the Cache ID of your cache +- **$API_KEY** - The LangCache API token ## Examples