Skip to content

Commit b0e3852

Browse files
committed
Update curl client
1 parent 003a1a8 commit b0e3852

4 files changed

Lines changed: 70 additions & 51 deletions

File tree

README.md

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Semantic Memory
22

3-
**Semantic Memory** is an open-source library and service specializing in the
4-
efficient indexing of datasets through custom continuous data pipelines.
3+
**Semantic Memory** is an open-source library and [service](dotnet/Service)
4+
specialized in the efficient indexing of datasets through custom continuous data
5+
pipelines.
56

67
![image](https://github.com/microsoft/semantic-memory/assets/371009/31894afa-d19e-4e9b-8d0f-cb889bf5c77f)
78

8-
Utilizing advanced embeddings and LLMs, the system enables natural language
9+
Utilizing advanced embeddings and LLMs, the system enables Natural Language
910
querying for obtaining answers from the indexed data, complete with citations
1011
and links to the original sources.
1112

@@ -18,19 +19,23 @@ Semantic Memory enhances data-driven features in applications built using SK.
1819
> ℹ️ **NOTE**: the documentation below is work in progress, will evolve quickly
1920
> as is not fully functional yet.
2021
21-
# Examples
22+
# Importing memory in serverless mode
2223

23-
## Importing memory, locally, without deployments
24+
Semantic Memory works and scales at best when running as a service, allowing to
25+
ingest thousands of documents and information without blocking your app.
2426

25-
Importing documents into your Semantic Memory can be as simple as this:
27+
However, you can use Semantic Memory also serverless, embedding the `MemoryPipelineClient`
28+
in your app. Importing documents into your Semantic Memory can be as simple as this:
2629

2730
```csharp
2831
var memory = new MemoryPipelineClient();
2932

33+
# Import a file (default user)
3034
await memory.ImportFileAsync("meeting-transcript.docx");
3135

36+
# Import a file specifying a User and Tags
3237
await memory.ImportFileAsync("business-plan.docx",
33-
new DocumentDetails("file1", "user0022")
38+
new DocumentDetails("file1", "user@some.email")
3439
.AddTag("collection", "business")
3540
.AddTag("collection", "plans")
3641
.AddTag("type", "doc"));
@@ -41,26 +46,28 @@ Asking questions
4146
```csharp
4247
string answer1 = await memory.AskAsync("How many people attended the meeting?");
4348

44-
string answer2 = await memory.AskAsync("what's the project timeline?", "user0022");
49+
string answer2 = await memory.AskAsync("what's the project timeline?", "user@some.email");
4550
```
4651

4752
The code leverages the default documents ingestion pipeline:
4853

49-
1. Extract text
50-
2. Partition the text in small chunks
51-
3. Extract embedding
52-
4. Save embedding into a vector index
54+
1. Extract text: recognize the file format and extract the information
55+
2. Partition the text in small chunks, to optimize search
56+
3. Extract embedding using an LLM embedding generator
57+
4. Save embedding into a vector index such as
58+
[Azure Cognitive Search](https://learn.microsoft.com/en-us/azure/search/vector-search-overview),
59+
[Qdrant](https://qdrant.tech/) or other DBs.
5360

54-
Data is also organized by users, protecting information and allowing to
55-
organize private information. And memories can be labelled and organized
56-
using **Tags**.
61+
Documents are organized by users, safeguarding their private information.
62+
Furthermore, memories can be categorized and structured using **tags**, enabling
63+
efficient search and retrieval through faceted navigation.
5764

5865
## Import memory using Semantic Memory Web Service
5966

6067
Depending on your scenarios, you might want to run all the code **locally
6168
inside your process, or remotely through an asynchronous service.**
6269

63-
If you're importing small files, and need only C# or Python, and can block
70+
If you're importing small files, and need only C# or only Python, and can block
6471
the process during the import, local-in-process execution can be fine, using
6572
the **MemoryPipelineClient** seen above.
6673

dotnet/CoreLib/WebService/UploadRequest.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,30 @@ public class UploadRequest
6767
{
6868
if (key == documentIdField || key == userIdField || !form.TryGetValue(key, out StringValues values)) { continue; }
6969

70-
foreach (var x in values)
70+
ValidateTagName(key);
71+
foreach (string? x in values)
7172
{
7273
result.Tags.Add(key, x);
7374
}
7475
}
7576

7677
return (result, true, string.Empty);
7778
}
79+
80+
private static void ValidateTagName(string key)
81+
{
82+
if (key.Contains("="))
83+
{
84+
throw new SemanticMemoryException("A tag name cannot contain the '=' symbol");
85+
}
86+
87+
if (key is Constants.ReservedUserIdTag
88+
or Constants.ReservedDocIdTag
89+
or Constants.ReservedFileIdTag
90+
or Constants.ReservedFilePartitionTag
91+
or Constants.ReservedFileTypeTag)
92+
{
93+
throw new SemanticMemoryException($"The tag name '{key}' is reserved for internal use.");
94+
}
95+
}
7896
}

samples/curl/example.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/"
77
../../curl/upload-file.sh -f test.pdf \
88
-s http://127.0.0.1:9001/upload \
99
-u curlUser \
10-
-c curlDataCollection \
10+
-t "type=test" \
1111
-i curlExample01

tools/upload-file.sh

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@ Help for Bash script
1313
1414
Usage:
1515
16-
./upload-file.sh -f <file path> -u <id> -c <list> -i <id> -s <url>
16+
./upload-file.sh -s <url> -f <file path> -u <id> [-i <id>] [-t <tag1> -t <tag2> -t <tag3> (...)]
17+
18+
-s web service URL (required) Semantic Memory web service URL.
19+
-f file path (required) Path to the document to upload.
20+
-u userId (required) User ID.
21+
22+
-i document ID (optional) Unique identifier for the document uploaded.
23+
-t "key=value" (optional) Key-Value tag. Multiple tags and values per tag can be set.
1724
18-
-f file path Path to the document to upload.
19-
-u userId User ID.
20-
-c "coll1 coll2 .." List of collection IDs separated by a space.
21-
-i document ID Unique identifier for the document uploaded.
22-
-s web service URL Semantic Memory web service URL.
2325
-h Print this help content.
2426
2527
2628
Example:
2729
28-
./upload-file.sh -f myFile.pdf -u me -c "notes meetings" -i "bash test" -s http://127.0.0.1:9001/upload
30+
./upload-file.sh -f myFile.pdf -u me -t "type=notes" -t "type=test" -i "bash test" -s http://127.0.0.1:9001/upload
2931
3032
3133
For more information visit https://github.com/microsoft/semantic-memory
@@ -36,6 +38,10 @@ _EOF_
3638
readParameters() {
3739
while [ "$1" != "" ]; do
3840
case $1 in
41+
-s)
42+
shift
43+
SERVICE_URL=$1
44+
;;
3945
-f)
4046
shift
4147
FILENAME=$1
@@ -44,17 +50,13 @@ readParameters() {
4450
shift
4551
USER_ID=$1
4652
;;
47-
-c)
48-
shift
49-
COLLECTIONS=$1
50-
;;
5153
-i)
5254
shift
5355
DOCUMENT_ID=$1
5456
;;
55-
-s)
57+
-t)
5658
shift
57-
SERVICE_URL=$1
59+
TAGS="$TAGS $1"
5860
;;
5961
*)
6062
help
@@ -83,27 +85,19 @@ validatePrameters() {
8385
help
8486
exit 1
8587
fi
86-
if [ -z "$USER_ID" ]; then
87-
echo "Please specify the user ID"
88+
if [ -z "$SERVICE_URL" ]; then
89+
echo "Please specify the web service URL"
8890
exit 2
8991
fi
90-
if [ -z "$COLLECTIONS" ]; then
91-
echo "Please specify the list of collection IDs"
92+
if [ -z "$USER_ID" ]; then
93+
echo "Please specify the user ID"
9294
exit 3
9395
fi
94-
if [ -z "$DOCUMENT_ID" ]; then
95-
echo "Please specify a unique document ID"
96-
exit 4
97-
fi
98-
if [ -z "$SERVICE_URL" ]; then
99-
echo "Please specify the web service URL"
100-
exit 5
101-
fi
10296
}
10397

10498
# Remove variables and functions from the environment, in case the script was sourced
10599
cleanupEnv() {
106-
unset FILENAME USER_ID COLLECTIONS DOCUMENT_ID SERVICE_URL
100+
unset FILENAME SERVICE_URL USER_ID TAGS DOCUMENT_ID
107101
unset -f help readParameters validatePrameters cleanupEnv exitScript
108102
}
109103

@@ -116,17 +110,17 @@ exitScript() {
116110
readParameters "$@"
117111
validatePrameters
118112

119-
# Handle list of collection IDs
120-
COLLECTIONS_FIELD=""
121-
for x in $COLLECTIONS; do
122-
COLLECTIONS_FIELD="${COLLECTIONS_FIELD} -F collections=\"${x}\""
113+
# Handle list of tags
114+
TAGS_FIELD=""
115+
for x in $TAGS; do
116+
TAGS_FIELD="${TAGS_FIELD} -F ${x}"
123117
done
124118

125119
# Send HTTP request using curl
126-
#set -x
120+
set -x
127121
curl -v \
128122
-F 'file1=@"'"${FILENAME}"'"' \
129-
-F 'user="'"${USER_ID}"'"' \
123+
-F 'userId="'"${USER_ID}"'"' \
130124
-F 'documentId="'"${DOCUMENT_ID}"'"' \
131-
$COLLECTIONS_FIELD \
125+
$TAGS_FIELD \
132126
$SERVICE_URL

0 commit comments

Comments
 (0)