-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.py
More file actions
116 lines (94 loc) · 3.07 KB
/
database.py
File metadata and controls
116 lines (94 loc) · 3.07 KB
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
from configparser import ConfigParser
from dataclasses import dataclass
from typing import TypeAlias
import json
from typing import ClassVar
import requests
Dictionary : TypeAlias = list[tuple[str, str]]
class DBError(Exception):
pass
class UserTableKeyError(DBError):
pass
class NonExistingUserError(DBError):
pass
@dataclass
class DictionariesTable:
region: str
service: str
cluster: str
database: str
collection: str
api_key: str
_url_common: ClassVar[
str
] = "data.mongodb-api.com/app/data-zvtvp/endpoint/data/v1/action"
@property
def headers(self) -> dict[str, str]:
return {
"Content-Type": "application/json",
"Access-Control-Request-Headers": "*",
"api-key": self.api_key,
}
@property
def default_payload(self) -> dict[str, str]:
return {
"collection": self.collection,
"database": self.database,
"dataSource": self.cluster,
}
def url(self, method: str) -> str:
return f"https://{self.region}.{self.service}.{self._url_common}/{method}"
@staticmethod
def get_projection(fields: list[str]) -> dict:
projection = {"_id": False} | {field: True for field in fields}
return projection
def request(self, method: str, payload: dict) -> dict:
payload |= self.default_payload
return requests.post(
url=self.url(method),
headers=self.headers,
data=json.dumps(payload),
).json()
def get_dictionary(self, index: int) -> Dictionary:
payload = {
"filter": {"index": index},
"projection": self.get_projection(["dictionary"]),
}
response = self.request("findOne", payload)
document = response["document"]
if document is None:
return []
return document["dictionary"]
def get_index(self, inserted_id: str) -> int:
payload = {
"filter": {"_id": {"$oid": inserted_id}},
"projection": self.get_projection(["index"])
}
while True:
response = self.request("findOne", payload)
document = response["document"]
index = document.get("index", 0)
if index:
return index
def insert_dictionary(self, dictionary: Dictionary) -> int:
payload = {
"document": {
"dictionary": dictionary,
}
}
response = self.request("insertOne", payload)
inserted_id = response["insertedId"]
return self.get_index(inserted_id)
@classmethod
def from_config(cls, path: str = "config.ini") -> "DictionariesTable":
config = ConfigParser()
config.read(path)
mongoDB_section = config["MONGODB"]
return cls(
mongoDB_section["region"],
mongoDB_section["service"],
mongoDB_section["cluster"],
mongoDB_section["database"],
mongoDB_section["collection"],
mongoDB_section["api-key"],
)