Spaces:
YZ03
/
Runtime error

File size: 4,313 Bytes
d99956a
eb7475d
4c6ab9d
eb7475d
 
4c6ab9d
 
 
d99956a
 
4c6ab9d
eb7475d
 
d99956a
4c6ab9d
eb7475d
 
 
1e54781
eb7475d
 
 
1e54781
4c6ab9d
eb7475d
 
d99956a
eb7475d
 
4c6ab9d
d99956a
 
b25b520
d99956a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b25b520
 
 
 
 
 
 
d99956a
 
b25b520
d99956a
 
 
4c6ab9d
b25b520
eb7475d
b25b520
eb7475d
1e54781
4c6ab9d
d99956a
4c6ab9d
b25b520
 
 
 
 
 
4c6ab9d
eb7475d
d99956a
 
 
 
 
 
 
b25b520
d99956a
 
 
 
 
 
4c6ab9d
d99956a
 
 
 
 
b25b520
d99956a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eb7475d
 
d99956a
 
eb7475d
 
 
 
d99956a
eb7475d
 
 
4c6ab9d
eb7475d
 
 
b25b520
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from tqdm import tqdm
import os
import chardet
import numpy as np
from pinecone import Pinecone
from langchain.docstore.document import Document as LangchainDocument
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OpenAIEmbeddings
import spacy


# Constants
DATA_DIR = "data"
JOURNAL_DIR = "journals"

# Load environment variables
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
PINECONE_API_KEY = os.environ["PINECONE_API_KEY"]
PINECONE_INDEX = os.environ["PINECONE_INDEX"]

# Initialize Pinecone
pc = Pinecone(api_key=PINECONE_API_KEY)
index = pc.Index(PINECONE_INDEX)

# Initialize embedding model
embedding_model = OpenAIEmbeddings(
    model="text-embedding-3-small",
    api_key=OPENAI_API_KEY
)

nlp = spacy.load("xx_sent_ud_sm")  # For multilingual support including Arabic

def sentence_overlap_chunks(text, chunk_size=2000):
    doc = nlp(text)
    sentences = [sent.text.strip() for sent in doc.sents]
    
    chunks = []
    i = 0

    while i < len(sentences):
        chunk = []
        length = 0
        start_i = i

        # Fill chunk up to chunk_size characters
        while i < len(sentences) and length + len(sentences[i]) <= chunk_size:
            chunk.append(sentences[i])
            length += len(sentences[i]) + 1
            i += 1

        # Join and store chunk
        if chunk:
            try:
                chunk = " ".join(chunk)
                chunks.append(chunk)
                i+=1
            except:
                print("can't process line.")
                i+=4

        # Overlap: start next chunk with last sentence of current chunk
        i = i - 3

    return chunks


# for data
for filename in os.listdir(DATA_DIR):
    if filename.endswith(".pdf"):
        filepath = os.path.join(DATA_DIR, filename)
        namespace = "ns4"

        print(f"Processing {filename} → namespace: {namespace}")

        reader = fitz.open(filepath)
        content = ""
        for page in reader:
            text = page.get_text()
            if text:
                content += text + "\n"

        # Wrap in Langchain doc
        docs_processed = sentence_overlap_chunks(content)
        
        # Embed and prepare for upsert
        upsert_data = []
        for i, chunk in tqdm(enumerate(docs_processed), total=len(docs_processed), desc="Embedding chunks"):
            vector = embedding_model.embed_query(chunk)
            upsert_data.append({
                "id": f"{filename[:-4]}_chunk_{i}",
                "values": vector,
                "metadata": {
                    "text": chunk,
                    "source": filename
                }
            })

        # Upsert to Pinecone under this file's namespace
        print(f"⬆️ Upserting {len(upsert_data)} vectors to namespace '{namespace}'...")
        index.upsert(vectors=upsert_data, namespace=namespace)
        print(f"✅ Done with {filename}\n")

# for journals
for filename in os.listdir(JOURNAL_DIR):
    if filename.endswith(".txt"):
        filepath = os.path.join(JOURNAL_DIR, filename)
        namespace = filename[:-4]

        print(f"Processing {filename} → namespace: {namespace}")

        # Detect encoding
        with open(filepath, "rb") as f:
            raw_data = f.read()
            encoding = chardet.detect(raw_data)['encoding']

        # Read file
        with open(filepath, "r", encoding=encoding) as f:
            content = f.read()

        # Wrap in Langchain doc
        docs_processed = sentence_overlap_chunks(content, chunk_size=400)
        
        # Embed and prepare for upsert
        upsert_data = []
        for i, chunk in tqdm(enumerate(docs_processed), total=len(docs_processed), desc="Embedding chunks"):
            vector = embedding_model.embed_query(chunk)
            upsert_data.append({
                "id": f"{namespace}_chunk_{i}",
                "values": vector,
                "metadata": {
                    "text": chunk,
                    "source": filename
                }
            })

        # Upsert to Pinecone under this file's namespace
        print(f"⬆️ Upserting {len(upsert_data)} vectors to namespace '{namespace}'...")
        index.upsert(vectors=upsert_data, namespace=namespace)
        print(f"✅ Done with {filename}\n")