documents.py 4.18 KB
Newer Older
1
2
from pydantic import BaseModel, ConfigDict
from typing import List, Optional
Timothy J. Baek's avatar
Timothy J. Baek committed
3
import time
4
import logging
Timothy J. Baek's avatar
Timothy J. Baek committed
5

6
from sqlalchemy import String, Column, BigInteger, Text
Timothy J. Baek's avatar
Timothy J. Baek committed
7

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
8
from apps.webui.internal.db import Base, get_db
Timothy J. Baek's avatar
Timothy J. Baek committed
9
10
11

import json

12
from config import SRC_LOG_LEVELS
Timothy J. Baek's avatar
Timothy J. Baek committed
13

14
15
16
log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MODELS"])

Timothy J. Baek's avatar
Timothy J. Baek committed
17
18
19
20
21
####################
# Documents DB Schema
####################


22
23
class Document(Base):
    __tablename__ = "document"
Timothy J. Baek's avatar
Timothy J. Baek committed
24

25
26
    collection_name = Column(String, primary_key=True)
    name = Column(String, unique=True)
27
28
29
    title = Column(Text)
    filename = Column(Text)
    content = Column(Text, nullable=True)
30
31
    user_id = Column(String)
    timestamp = Column(BigInteger)
Timothy J. Baek's avatar
Timothy J. Baek committed
32
33
34


class DocumentModel(BaseModel):
35
36
    model_config = ConfigDict(from_attributes=True)

Timothy J. Baek's avatar
Timothy J. Baek committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    collection_name: str
    name: str
    title: str
    filename: str
    content: Optional[str] = None
    user_id: str
    timestamp: int  # timestamp in epoch


####################
# Forms
####################


Timothy J. Baek's avatar
Timothy J. Baek committed
51
52
53
54
55
56
57
58
59
60
class DocumentResponse(BaseModel):
    collection_name: str
    name: str
    title: str
    filename: str
    content: Optional[dict] = None
    user_id: str
    timestamp: int  # timestamp in epoch


Timothy J. Baek's avatar
Timothy J. Baek committed
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class DocumentUpdateForm(BaseModel):
    name: str
    title: str


class DocumentForm(DocumentUpdateForm):
    collection_name: str
    filename: str
    content: Optional[str] = None


class DocumentsTable:

    def insert_new_doc(
75
        self, user_id: str, form_data: DocumentForm
Timothy J. Baek's avatar
Timothy J. Baek committed
76
    ) -> Optional[DocumentModel]:
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
77
        with get_db() as db:
Timothy J. Baek's avatar
Timothy J. Baek committed
78

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
            document = DocumentModel(
                **{
                    **form_data.model_dump(),
                    "user_id": user_id,
                    "timestamp": int(time.time()),
                }
            )

            try:
                result = Document(**document.model_dump())
                db.add(result)
                db.commit()
                db.refresh(result)
                if result:
                    return DocumentModel.model_validate(result)
                else:
                    return None
            except:
97
                return None
Timothy J. Baek's avatar
Timothy J. Baek committed
98

99
    def get_doc_by_name(self, name: str) -> Optional[DocumentModel]:
Timothy J. Baek's avatar
Timothy J. Baek committed
100
        try:
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
101
102
103
104
            with get_db() as db:

                document = db.query(Document).filter_by(name=name).first()
                return DocumentModel.model_validate(document) if document else None
Timothy J. Baek's avatar
Timothy J. Baek committed
105
106
107
        except:
            return None

108
    def get_docs(self) -> List[DocumentModel]:
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
109
110
111
112
113
        with get_db() as db:

            return [
                DocumentModel.model_validate(doc) for doc in db.query(Document).all()
            ]
Timothy J. Baek's avatar
Timothy J. Baek committed
114
115

    def update_doc_by_name(
116
        self, name: str, form_data: DocumentUpdateForm
Timothy J. Baek's avatar
Timothy J. Baek committed
117
118
    ) -> Optional[DocumentModel]:
        try:
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
119
120
121
122
123
124
125
126
127
128
129
            with get_db() as db:

                db.query(Document).filter_by(name=name).update(
                    {
                        "title": form_data.title,
                        "name": form_data.name,
                        "timestamp": int(time.time()),
                    }
                )
                db.commit()
                return self.get_doc_by_name(form_data.name)
130
        except Exception as e:
131
            log.exception(e)
Timothy J. Baek's avatar
Timothy J. Baek committed
132
133
            return None

Timothy J. Baek's avatar
Timothy J. Baek committed
134
    def update_doc_content_by_name(
135
        self, name: str, updated: dict
Timothy J. Baek's avatar
Timothy J. Baek committed
136
137
    ) -> Optional[DocumentModel]:
        try:
138
139
140
141
            doc = self.get_doc_by_name(name)
            doc_content = json.loads(doc.content if doc.content else "{}")
            doc_content = {**doc_content, **updated}

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
142
143
144
145
146
147
148
149
150
151
            with get_db() as db:

                db.query(Document).filter_by(name=name).update(
                    {
                        "content": json.dumps(doc_content),
                        "timestamp": int(time.time()),
                    }
                )
                db.commit()
                return self.get_doc_by_name(name)
Timothy J. Baek's avatar
Timothy J. Baek committed
152
        except Exception as e:
153
            log.exception(e)
Timothy J. Baek's avatar
Timothy J. Baek committed
154
155
            return None

156
    def delete_doc_by_name(self, name: str) -> bool:
Timothy J. Baek's avatar
Timothy J. Baek committed
157
        try:
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
158
159
160
161
            with get_db() as db:

                db.query(Document).filter_by(name=name).delete()
                return True
Timothy J. Baek's avatar
Timothy J. Baek committed
162
163
164
165
        except:
            return False


166
Documents = DocumentsTable()