erioon 0.0.1__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {erioon-0.0.1 → erioon-0.0.3}/PKG-INFO +1 -1
- erioon-0.0.3/README.md +2 -0
- erioon-0.0.3/erioon/client.py +194 -0
- erioon-0.0.3/erioon/collection.py +191 -0
- erioon-0.0.3/erioon/database.py +31 -0
- {erioon-0.0.1 → erioon-0.0.3}/erioon.egg-info/PKG-INFO +1 -1
- {erioon-0.0.1 → erioon-0.0.3}/erioon.egg-info/SOURCES.txt +2 -0
- {erioon-0.0.1 → erioon-0.0.3}/setup.py +1 -1
- erioon-0.0.1/erioon/client.py +0 -106
- erioon-0.0.1/erioon/database.py +0 -17
- {erioon-0.0.1 → erioon-0.0.3}/LICENSE +0 -0
- {erioon-0.0.1 → erioon-0.0.3}/erioon/auth.py +0 -0
- {erioon-0.0.1 → erioon-0.0.3}/erioon.egg-info/dependency_links.txt +0 -0
- {erioon-0.0.1 → erioon-0.0.3}/erioon.egg-info/requires.txt +0 -0
- {erioon-0.0.1 → erioon-0.0.3}/erioon.egg-info/top_level.txt +0 -0
- {erioon-0.0.1 → erioon-0.0.3}/setup.cfg +0 -0
erioon-0.0.3/README.md
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
import os
|
2
|
+
import json
|
3
|
+
import requests
|
4
|
+
from erioon.database import Database
|
5
|
+
|
6
|
+
class ErioonClient:
|
7
|
+
"""
|
8
|
+
Client SDK for interacting with the Erioon API.
|
9
|
+
|
10
|
+
Handles user authentication, token caching, and accessing user databases.
|
11
|
+
|
12
|
+
Attributes:
|
13
|
+
email (str): User email for login.
|
14
|
+
password (str): User password for login.
|
15
|
+
base_url (str): Base URL of the Erioon API.
|
16
|
+
user_id (str | None): Authenticated user ID.
|
17
|
+
error (str | None): Stores error messages if login fails.
|
18
|
+
token_path (str): Local path to cached authentication token.
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self, email, password, base_url="https://sdk.erioon.com"):
|
22
|
+
"""
|
23
|
+
Initialize ErioonClient instance, attempts to load cached token or perform login.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
email (str): User email for authentication.
|
27
|
+
password (str): User password for authentication.
|
28
|
+
base_url (str, optional): Base API URL. Defaults to "https://sdk.erioon.com".
|
29
|
+
"""
|
30
|
+
self.email = email
|
31
|
+
self.password = password
|
32
|
+
self.base_url = base_url
|
33
|
+
self.user_id = None
|
34
|
+
self.error = None
|
35
|
+
self.token_path = os.path.expanduser(f"~/.erioon_token_{self._safe_filename(email)}")
|
36
|
+
|
37
|
+
try:
|
38
|
+
self.user_id = self._load_or_login()
|
39
|
+
except Exception as e:
|
40
|
+
self.error = str(e)
|
41
|
+
|
42
|
+
def _safe_filename(self, text):
|
43
|
+
"""
|
44
|
+
Converts a string into a safe filename by replacing non-alphanumeric chars with underscores.
|
45
|
+
|
46
|
+
Args:
|
47
|
+
text (str): Input string to convert.
|
48
|
+
|
49
|
+
Returns:
|
50
|
+
str: Sanitized filename-safe string.
|
51
|
+
"""
|
52
|
+
return "".join(c if c.isalnum() else "_" for c in text)
|
53
|
+
|
54
|
+
def _load_or_login(self):
|
55
|
+
"""
|
56
|
+
Load cached user_id token from local storage or perform login if not cached.
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
str: User ID from token or fresh login.
|
60
|
+
|
61
|
+
Raises:
|
62
|
+
Exception: If login fails.
|
63
|
+
"""
|
64
|
+
if os.path.exists(self.token_path):
|
65
|
+
with open(self.token_path, "r") as f:
|
66
|
+
token_data = json.load(f)
|
67
|
+
user_id = token_data.get("user_id")
|
68
|
+
if user_id:
|
69
|
+
return user_id
|
70
|
+
|
71
|
+
return self._do_login_and_cache()
|
72
|
+
|
73
|
+
def _do_login_and_cache(self):
|
74
|
+
"""
|
75
|
+
Perform login to API and cache the user_id token locally.
|
76
|
+
|
77
|
+
Returns:
|
78
|
+
str: User ID from successful login.
|
79
|
+
|
80
|
+
Raises:
|
81
|
+
Exception: If login fails.
|
82
|
+
"""
|
83
|
+
user_id = self._login()
|
84
|
+
with open(self.token_path, "w") as f:
|
85
|
+
json.dump({"user_id": user_id}, f)
|
86
|
+
return user_id
|
87
|
+
|
88
|
+
def _login(self):
|
89
|
+
"""
|
90
|
+
Authenticate with Erioon API using email and password.
|
91
|
+
|
92
|
+
Returns:
|
93
|
+
str: User ID on successful authentication.
|
94
|
+
|
95
|
+
Raises:
|
96
|
+
Exception: If credentials are invalid.
|
97
|
+
"""
|
98
|
+
url = f"{self.base_url}/login_with_credentials"
|
99
|
+
payload = {"email": self.email, "password": self.password}
|
100
|
+
headers = {"Content-Type": "application/json"}
|
101
|
+
|
102
|
+
response = requests.post(url, json=payload, headers=headers)
|
103
|
+
if response.status_code == 200:
|
104
|
+
return response.text.strip()
|
105
|
+
else:
|
106
|
+
raise Exception("Invalid account")
|
107
|
+
|
108
|
+
def _clear_cached_token(self):
|
109
|
+
"""
|
110
|
+
Remove cached token file and reset user_id to None.
|
111
|
+
"""
|
112
|
+
if os.path.exists(self.token_path):
|
113
|
+
os.remove(self.token_path)
|
114
|
+
self.user_id = None
|
115
|
+
|
116
|
+
def __getitem__(self, db_id):
|
117
|
+
"""
|
118
|
+
Access a Database object by database ID.
|
119
|
+
|
120
|
+
Args:
|
121
|
+
db_id (str): The ID of the database to access.
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
Database: An instance representing the database.
|
125
|
+
|
126
|
+
Raises:
|
127
|
+
ValueError: If client is not authenticated.
|
128
|
+
Exception: For other API errors not related to database existence.
|
129
|
+
|
130
|
+
Handles:
|
131
|
+
On database-related errors, tries to relogin once. If relogin fails, returns "Login error".
|
132
|
+
If database still not found after relogin, returns a formatted error message.
|
133
|
+
"""
|
134
|
+
if not self.user_id:
|
135
|
+
raise ValueError("Client not authenticated. Cannot access database.")
|
136
|
+
|
137
|
+
try:
|
138
|
+
return self._get_database_info(db_id)
|
139
|
+
except Exception as e:
|
140
|
+
err_msg = str(e).lower()
|
141
|
+
if f"database with {db_id.lower()}" in err_msg or "database" in err_msg:
|
142
|
+
self._clear_cached_token()
|
143
|
+
try:
|
144
|
+
self.user_id = self._do_login_and_cache()
|
145
|
+
except Exception:
|
146
|
+
return "Login error"
|
147
|
+
|
148
|
+
try:
|
149
|
+
return self._get_database_info(db_id)
|
150
|
+
except Exception:
|
151
|
+
return f"❌ Database with _id {db_id} ..."
|
152
|
+
else:
|
153
|
+
raise e
|
154
|
+
|
155
|
+
def _get_database_info(self, db_id):
|
156
|
+
"""
|
157
|
+
Helper method to fetch database info from API and instantiate a Database object.
|
158
|
+
|
159
|
+
Args:
|
160
|
+
db_id (str): The database ID to fetch.
|
161
|
+
|
162
|
+
Returns:
|
163
|
+
Database: Database instance with the fetched info.
|
164
|
+
|
165
|
+
Raises:
|
166
|
+
Exception: If API returns an error.
|
167
|
+
"""
|
168
|
+
payload = {"user_id": self.user_id, "db_id": db_id}
|
169
|
+
headers = {"Content-Type": "application/json"}
|
170
|
+
|
171
|
+
response = requests.post(f"{self.base_url}/db_info", json=payload, headers=headers)
|
172
|
+
|
173
|
+
if response.status_code == 200:
|
174
|
+
db_info = response.json()
|
175
|
+
return Database(self.user_id, db_info)
|
176
|
+
else:
|
177
|
+
try:
|
178
|
+
error_json = response.json()
|
179
|
+
error_msg = error_json.get("error", response.text)
|
180
|
+
except Exception:
|
181
|
+
error_msg = response.text
|
182
|
+
raise Exception(error_msg)
|
183
|
+
|
184
|
+
def __str__(self):
|
185
|
+
"""
|
186
|
+
String representation: returns user_id if authenticated, else the error message.
|
187
|
+
"""
|
188
|
+
return self.user_id if self.user_id else self.error
|
189
|
+
|
190
|
+
def __repr__(self):
|
191
|
+
"""
|
192
|
+
Developer-friendly string representation of the client instance.
|
193
|
+
"""
|
194
|
+
return f"<ErioonClient user_id={self.user_id}>" if self.user_id else f"<ErioonClient error='{self.error}'>"
|
@@ -0,0 +1,191 @@
|
|
1
|
+
import json
|
2
|
+
import requests
|
3
|
+
from colorama import Fore, Style, init
|
4
|
+
|
5
|
+
init(autoreset=True)
|
6
|
+
|
7
|
+
class Collection:
|
8
|
+
def __init__(
|
9
|
+
self,
|
10
|
+
user_id,
|
11
|
+
db_id,
|
12
|
+
coll_id,
|
13
|
+
metadata,
|
14
|
+
base_url: str = "https://sdk.erioon.com",
|
15
|
+
):
|
16
|
+
"""
|
17
|
+
Initialize a Collection instance.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
user_id (str): Authenticated user ID.
|
21
|
+
db_id (str): Database ID.
|
22
|
+
coll_id (str): Collection ID.
|
23
|
+
metadata (dict): Collection metadata.
|
24
|
+
base_url (str): Base URL of the Erioon API.
|
25
|
+
"""
|
26
|
+
self.user_id = user_id
|
27
|
+
self.db_id = db_id
|
28
|
+
self.coll_id = coll_id
|
29
|
+
self.metadata = metadata
|
30
|
+
self.base_url = base_url.rstrip("/")
|
31
|
+
|
32
|
+
def _print_loading(self) -> None:
|
33
|
+
"""Print a green loading message to the terminal."""
|
34
|
+
print(Fore.CYAN + "Erioon is loading..." + Style.RESET_ALL)
|
35
|
+
|
36
|
+
# ---------- READ ---------- #
|
37
|
+
def get_all(self):
|
38
|
+
"""
|
39
|
+
Retrieve all documents from this collection.
|
40
|
+
|
41
|
+
Usage:
|
42
|
+
result = collection.get_all()
|
43
|
+
"""
|
44
|
+
self._print_loading()
|
45
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/get_all"
|
46
|
+
response = requests.get(url)
|
47
|
+
try:
|
48
|
+
response.raise_for_status()
|
49
|
+
return response.json()
|
50
|
+
except requests.HTTPError as e:
|
51
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
52
|
+
|
53
|
+
def get_specific(self, filters: dict | None = None, limit: int = 1000):
|
54
|
+
"""
|
55
|
+
Retrieve documents matching filters.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
filters (dict): Field/value pairs for filtering.
|
59
|
+
limit (int): Max number of docs to retrieve (max 500,000).
|
60
|
+
|
61
|
+
Usage:
|
62
|
+
result = collection.get_specific(filters={"name": "John"}, limit=100)
|
63
|
+
"""
|
64
|
+
if limit > 500_000:
|
65
|
+
raise ValueError("Limit of 500,000 exceeded")
|
66
|
+
self._print_loading()
|
67
|
+
|
68
|
+
if filters is None:
|
69
|
+
filters = {}
|
70
|
+
|
71
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/get_specific"
|
72
|
+
params = {**filters, "limit": limit}
|
73
|
+
response = requests.get(url, params=params)
|
74
|
+
try:
|
75
|
+
response.raise_for_status()
|
76
|
+
return response.json()
|
77
|
+
except requests.HTTPError as e:
|
78
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
79
|
+
|
80
|
+
# ---------- CREATE ---------- #
|
81
|
+
def insert_one(self, document: dict):
|
82
|
+
"""
|
83
|
+
Insert a single document.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
document (dict): The document to insert.
|
87
|
+
|
88
|
+
Usage:
|
89
|
+
new_doc = {"name": "Alice", "age": 25}
|
90
|
+
result = collection.insert_one(new_doc)
|
91
|
+
"""
|
92
|
+
self._print_loading()
|
93
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/insert_one"
|
94
|
+
response = requests.post(url, json=document, headers={"Content-Type": "application/json"})
|
95
|
+
try:
|
96
|
+
response.raise_for_status()
|
97
|
+
return response.json()
|
98
|
+
except requests.HTTPError as e:
|
99
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
100
|
+
|
101
|
+
def insert_many(self, documents: list):
|
102
|
+
"""
|
103
|
+
Insert multiple documents at once.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
documents (list): List of dicts representing documents.
|
107
|
+
|
108
|
+
Usage:
|
109
|
+
docs = [{"name": "A"}, {"name": "B"}]
|
110
|
+
result = collection.insert_many(docs)
|
111
|
+
"""
|
112
|
+
self._print_loading()
|
113
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/insert_many"
|
114
|
+
response = requests.post(url, json={"records": documents})
|
115
|
+
try:
|
116
|
+
response.raise_for_status()
|
117
|
+
return response.json()
|
118
|
+
except requests.HTTPError as e:
|
119
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
120
|
+
|
121
|
+
# ---------- DELETE ---------- #
|
122
|
+
def delete_one(self, filter_query: dict):
|
123
|
+
"""
|
124
|
+
Delete a single document matching the query.
|
125
|
+
|
126
|
+
Args:
|
127
|
+
filter_query (dict): A query to match one document.
|
128
|
+
|
129
|
+
Usage:
|
130
|
+
result = collection.delete_one({"name": "John"})
|
131
|
+
"""
|
132
|
+
self._print_loading()
|
133
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/delete_one"
|
134
|
+
response = requests.delete(url, json=filter_query)
|
135
|
+
try:
|
136
|
+
response.raise_for_status()
|
137
|
+
return response.json()
|
138
|
+
except requests.HTTPError as e:
|
139
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
140
|
+
|
141
|
+
def delete_many(self, filter_query: dict):
|
142
|
+
"""
|
143
|
+
Delete all documents matching the query.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
filter_query (dict): A query to match multiple documents.
|
147
|
+
|
148
|
+
Usage:
|
149
|
+
result = collection.delete_many({"status": "inactive"})
|
150
|
+
"""
|
151
|
+
self._print_loading()
|
152
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/delete_many"
|
153
|
+
response = requests.delete(url, json=filter_query)
|
154
|
+
try:
|
155
|
+
response.raise_for_status()
|
156
|
+
return response.json()
|
157
|
+
except requests.HTTPError as e:
|
158
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
159
|
+
|
160
|
+
# ---------- UPDATE ---------- #
|
161
|
+
def update_query(self, filter_query: dict, update_query: dict):
|
162
|
+
"""
|
163
|
+
Update documents matching a filter query.
|
164
|
+
|
165
|
+
Args:
|
166
|
+
filter_query (dict): Query to find documents.
|
167
|
+
update_query (dict): Update operations to apply.
|
168
|
+
|
169
|
+
Usage:
|
170
|
+
result = collection.update_query(
|
171
|
+
{"age": {"$gt": 30}},
|
172
|
+
{"$set": {"status": "senior"}}
|
173
|
+
)
|
174
|
+
"""
|
175
|
+
self._print_loading()
|
176
|
+
url = f"{self.base_url}/{self.user_id}/{self.db_id}/{self.coll_id}/update_query"
|
177
|
+
response = requests.patch(url, json={"filter_query": filter_query, "update_query": update_query})
|
178
|
+
try:
|
179
|
+
response.raise_for_status()
|
180
|
+
return response.json()
|
181
|
+
except requests.HTTPError as e:
|
182
|
+
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
183
|
+
|
184
|
+
# ---------- dunder helpers ---------- #
|
185
|
+
def __str__(self) -> str:
|
186
|
+
"""Return a human-readable JSON string of collection metadata."""
|
187
|
+
return json.dumps(self.metadata, indent=4)
|
188
|
+
|
189
|
+
def __repr__(self) -> str:
|
190
|
+
"""Return a developer-friendly representation of the object."""
|
191
|
+
return f"<Collection coll_id={self.coll_id}>"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import json
|
2
|
+
from erioon.collection import Collection
|
3
|
+
|
4
|
+
class Database:
|
5
|
+
def __init__(self, user_id, metadata):
|
6
|
+
self.user_id = user_id
|
7
|
+
self.metadata = metadata
|
8
|
+
self.db_id = metadata.get("database_info", {}).get("_id")
|
9
|
+
|
10
|
+
def __getitem__(self, collection_id):
|
11
|
+
try:
|
12
|
+
collections = self.metadata.get("database_info", {}).get("collections", {})
|
13
|
+
coll_meta = collections.get(collection_id)
|
14
|
+
|
15
|
+
if not coll_meta:
|
16
|
+
return "No collection found"
|
17
|
+
|
18
|
+
return Collection(
|
19
|
+
user_id=self.user_id,
|
20
|
+
db_id=self.db_id,
|
21
|
+
coll_id=collection_id,
|
22
|
+
metadata=coll_meta
|
23
|
+
)
|
24
|
+
except Exception:
|
25
|
+
return "Connection error"
|
26
|
+
|
27
|
+
def __str__(self):
|
28
|
+
return json.dumps(self.metadata, indent=4)
|
29
|
+
|
30
|
+
def __repr__(self):
|
31
|
+
return f"<Database db_id={self.db_id}>"
|
erioon-0.0.1/erioon/client.py
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
import requests
|
2
|
-
from erioon.database import Database
|
3
|
-
|
4
|
-
class ErioonClient:
|
5
|
-
"""
|
6
|
-
Represents an authenticated Erioon client session.
|
7
|
-
|
8
|
-
Handles user login via email and password, and stores either the user's ID
|
9
|
-
on success or an error message on failure.
|
10
|
-
|
11
|
-
Usage:
|
12
|
-
>>> client = ErioonClient("<EMAIL>:<PASSWORD>")
|
13
|
-
"""
|
14
|
-
|
15
|
-
def __init__(self, email, password, base_url="https://sdk.erioon.com"):
|
16
|
-
"""
|
17
|
-
Initializes the client and attempts login.
|
18
|
-
|
19
|
-
Args:
|
20
|
-
email (str): User email address.
|
21
|
-
password (str): User password.
|
22
|
-
base_url (str): The base URL of the Erioon API.
|
23
|
-
"""
|
24
|
-
self.email = email
|
25
|
-
self.password = password
|
26
|
-
self.base_url = base_url
|
27
|
-
self.user_id = None
|
28
|
-
self.error = None
|
29
|
-
|
30
|
-
try:
|
31
|
-
self.user_id = self.login()
|
32
|
-
except Exception as e:
|
33
|
-
self.error = str(e)
|
34
|
-
|
35
|
-
def login(self):
|
36
|
-
"""
|
37
|
-
Sends a login request to the Erioon API.
|
38
|
-
|
39
|
-
Returns:
|
40
|
-
str: User ID on successful login.
|
41
|
-
|
42
|
-
Raises:
|
43
|
-
Exception: If the login fails, with the error message from the server.
|
44
|
-
"""
|
45
|
-
url = f"{self.base_url}/login_with_credentials"
|
46
|
-
payload = {"email": self.email, "password": self.password}
|
47
|
-
headers = {"Content-Type": "application/json"}
|
48
|
-
|
49
|
-
response = requests.post(url, json=payload, headers=headers)
|
50
|
-
|
51
|
-
if response.status_code == 200:
|
52
|
-
return response.text.strip()
|
53
|
-
else:
|
54
|
-
raise Exception(response.text.strip())
|
55
|
-
|
56
|
-
def __str__(self):
|
57
|
-
"""
|
58
|
-
Called when print() or str() is used on the object.
|
59
|
-
|
60
|
-
Returns:
|
61
|
-
str: User ID if authenticated, or error message if not.
|
62
|
-
"""
|
63
|
-
return self.user_id if self.user_id else self.error
|
64
|
-
|
65
|
-
def __repr__(self):
|
66
|
-
"""
|
67
|
-
Called in developer tools or when inspecting the object.
|
68
|
-
|
69
|
-
Returns:
|
70
|
-
str: Formatted string showing either user ID or error.
|
71
|
-
"""
|
72
|
-
if self.user_id:
|
73
|
-
return f"<ErioonClient user_id={self.user_id}>"
|
74
|
-
else:
|
75
|
-
return f"<ErioonClient error='{self.error}'>"
|
76
|
-
|
77
|
-
def __getitem__(self, db_id):
|
78
|
-
"""
|
79
|
-
Get a Database object by its ID.
|
80
|
-
|
81
|
-
Calls the API to retrieve DB metadata and initializes a Database instance.
|
82
|
-
"""
|
83
|
-
if not self.user_id:
|
84
|
-
raise ValueError("Client not authenticated. Cannot access database.")
|
85
|
-
|
86
|
-
payload = {"user_id": self.user_id, "db_id": db_id}
|
87
|
-
headers = {"Content-Type": "application/json"}
|
88
|
-
|
89
|
-
response = requests.post(f"{self.base_url}/db_info", json=payload, headers=headers)
|
90
|
-
|
91
|
-
|
92
|
-
if response.status_code != 200:
|
93
|
-
db_error = response.json()
|
94
|
-
return db_error["error"]
|
95
|
-
|
96
|
-
db_info = response.json()
|
97
|
-
return Database(db_info)
|
98
|
-
|
99
|
-
def __str__(self):
|
100
|
-
return self.user_id if self.user_id else self.error
|
101
|
-
|
102
|
-
def __repr__(self):
|
103
|
-
if self.user_id:
|
104
|
-
return f"<ErioonClient user_id={self.user_id}>"
|
105
|
-
else:
|
106
|
-
return f"<ErioonClient error='{self.error}'>"
|
erioon-0.0.1/erioon/database.py
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
|
3
|
-
class Database:
|
4
|
-
def __init__(self, metadata):
|
5
|
-
self.metadata = metadata
|
6
|
-
|
7
|
-
def __getitem__(self, collection_id):
|
8
|
-
"""
|
9
|
-
Will return a Collection object (to be implemented in next steps).
|
10
|
-
"""
|
11
|
-
raise NotImplementedError("Collection access not implemented yet.")
|
12
|
-
|
13
|
-
def __str__(self):
|
14
|
-
return json.dumps(self.metadata, indent=4)
|
15
|
-
|
16
|
-
def __repr__(self):
|
17
|
-
return f"{self.metadata}"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|