erioon 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

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/client.py CHANGED
@@ -5,23 +5,12 @@ from datetime import datetime, timezone
5
5
  from erioon.database import Database
6
6
 
7
7
  class ErioonClient:
8
- """
9
- Client SDK for interacting with the Erioon API.
10
-
11
- Handles:
12
- - User authentication with email/password and API key
13
- - Token caching to avoid re-authenticating every time
14
- - SAS token expiration detection and auto-renewal
15
- - Access to user-specific databases
16
- """
17
-
18
8
  def __init__(self, api, email, password, base_url="https://sdk.erioon.com"):
19
9
  self.api = api
20
10
  self.email = email
21
11
  self.password = password
22
12
  self.base_url = base_url
23
13
  self.user_id = None
24
- self.error = None
25
14
  self.token_path = os.path.expanduser(f"~/.erioon_token_{self._safe_filename(email)}")
26
15
  self.login_metadata = None
27
16
 
@@ -29,42 +18,28 @@ class ErioonClient:
29
18
  self.login_metadata = self._load_or_login()
30
19
  self._update_metadata_fields()
31
20
  except Exception as e:
32
- self.error = str(e)
21
+ print(f"[ErioonClient] Initialization error: {e}")
33
22
 
34
23
  def _safe_filename(self, text):
35
- """
36
- Converts unsafe filename characters to underscores for cache file naming.
37
- """
38
24
  return "".join(c if c.isalnum() else "_" for c in text)
39
25
 
40
26
  def _do_login_and_cache(self):
41
- """
42
- Logs in to the API and writes the returned metadata (e.g. SAS token, user ID) to a local file.
43
- """
44
27
  metadata = self._login()
45
28
  with open(self.token_path, "w") as f:
46
29
  json.dump(metadata, f)
47
30
  return metadata
48
31
 
49
32
  def _load_or_login(self):
50
- """
51
- Tries to load the cached login metadata.
52
- If token is expired or file does not exist, performs a fresh login.
53
- """
54
33
  if os.path.exists(self.token_path):
55
34
  with open(self.token_path, "r") as f:
56
35
  metadata = json.load(f)
57
36
  if self._is_sas_expired(metadata):
58
- metadata = self._do_login_and_cache()
37
+ return self._do_login_and_cache()
59
38
  return metadata
60
39
  else:
61
40
  return self._do_login_and_cache()
62
41
 
63
42
  def _login(self):
64
- """
65
- Sends login request to Erioon API using API key, email, and password.
66
- Returns authentication metadata including SAS token.
67
- """
68
43
  url = f"{self.base_url}/login_with_credentials"
69
44
  payload = {"api_key": self.api, "email": self.email, "password": self.password}
70
45
  headers = {"Content-Type": "application/json"}
@@ -76,37 +51,30 @@ class ErioonClient:
76
51
  self._update_metadata_fields()
77
52
  return data
78
53
  else:
79
- raise Exception("Invalid account")
54
+ try:
55
+ msg = response.json().get("error", "Login failed")
56
+ except Exception:
57
+ msg = response.text
58
+ print(f"[ErioonClient] Login failed: {msg}")
59
+ raise RuntimeError(msg)
80
60
 
81
61
  def _update_metadata_fields(self):
82
- """
83
- Updates internal fields like user_id, database name, and cluster info
84
- from login metadata.
85
- """
86
62
  if self.login_metadata:
87
63
  self.user_id = self.login_metadata.get("_id")
88
- self.database = self.login_metadata.get("database")
89
64
  self.cluster = self.login_metadata.get("cluster")
65
+ self.database = self.login_metadata.get("database")
66
+ self.sas_tokens = self.login_metadata.get("sas_tokens", {})
90
67
 
91
68
  def _clear_cached_token(self):
92
- """
93
- Clears the locally cached authentication token and resets internal state.
94
- """
95
69
  if os.path.exists(self.token_path):
96
70
  os.remove(self.token_path)
97
71
  self.user_id = None
98
72
  self.login_metadata = None
99
73
 
100
74
  def _is_sas_expired(self, metadata):
101
- """
102
- Determines whether the SAS token has expired by comparing the 'sas_token_expiry'
103
- or 'expiry' field with the current UTC time.
104
- """
105
75
  expiry_str = metadata.get("sas_token_expiry") or metadata.get("expiry")
106
-
107
76
  if not expiry_str:
108
77
  return True
109
-
110
78
  try:
111
79
  expiry_dt = datetime.fromisoformat(expiry_str.replace("Z", "+00:00"))
112
80
  now = datetime.now(timezone.utc)
@@ -115,50 +83,45 @@ class ErioonClient:
115
83
  return True
116
84
 
117
85
  def __getitem__(self, db_id):
118
- """
119
- Allows syntax like `client["my_database_id"]` to access a database.
120
- If the token is expired or invalid, it attempts reauthentication.
121
- """
122
86
  if not self.user_id:
123
- raise ValueError("Client not authenticated. Cannot access database.")
87
+ print(f"[ErioonClient] Not authenticated. Cannot access database {db_id}.")
88
+ raise ValueError("Client not authenticated.")
124
89
 
125
90
  try:
126
91
  return self._get_database_info(db_id)
127
92
  except Exception as e:
128
- err_msg = str(e).lower()
129
- if f"database with {db_id.lower()}" in err_msg or "database" in err_msg:
130
- self._clear_cached_token()
131
- try:
132
- self.login_metadata = self._do_login_and_cache()
133
- self._update_metadata_fields()
134
- except Exception:
135
- return "Login error"
136
-
137
- try:
138
- return self._get_database_info(db_id)
139
- except Exception:
140
- return f"❌ Database with _id {db_id} ..."
141
- else:
142
- raise e
93
+ print(f"[ErioonClient] Access failed for DB {db_id}, retrying login... ({e})")
94
+ self._clear_cached_token()
95
+
96
+ try:
97
+ self.login_metadata = self._do_login_and_cache()
98
+ self._update_metadata_fields()
99
+ except Exception as login_error:
100
+ print(f"[ErioonClient] Re-login failed: {login_error}")
101
+ raise RuntimeError(login_error)
102
+
103
+ try:
104
+ return self._get_database_info(db_id)
105
+ except Exception as second_error:
106
+ print(f"[ErioonClient] DB fetch after re-auth failed: {second_error}")
107
+ raise RuntimeError(second_error)
143
108
 
144
109
  def _get_database_info(self, db_id):
145
- """
146
- Sends a POST request to fetch metadata for a given database ID.
147
- Returns a `Database` instance initialized with SAS URL and metadata.
148
- """
149
110
  payload = {"user_id": self.user_id, "db_id": db_id}
150
111
  headers = {"Content-Type": "application/json"}
151
-
152
112
  response = requests.post(f"{self.base_url}/db_info", json=payload, headers=headers)
153
113
 
154
114
  if response.status_code == 200:
155
115
  db_info = response.json()
116
+ sas_info = self.sas_tokens.get(db_id)
117
+ if not sas_info:
118
+ raise Exception(f"No SAS token info for database id {db_id}")
156
119
 
157
- container_url = self.login_metadata.get("container_url")
158
- sas_token = self.login_metadata.get("sas_token")
120
+ container_url = sas_info.get("container_url")
121
+ sas_token = sas_info.get("sas_token")
159
122
 
160
123
  if not container_url or not sas_token:
161
- raise Exception("Missing SAS URL components for storage access")
124
+ raise Exception("Missing SAS URL components")
162
125
 
163
126
  if not sas_token.startswith("?"):
164
127
  sas_token = "?" + sas_token
@@ -178,16 +141,10 @@ class ErioonClient:
178
141
  error_msg = error_json.get("error", response.text)
179
142
  except Exception:
180
143
  error_msg = response.text
181
- raise Exception(error_msg)
144
+ raise Exception(f"Failed to fetch database info: {error_msg}")
182
145
 
183
146
  def __str__(self):
184
- """
185
- Returns user_id or error string when printed.
186
- """
187
- return self.user_id if self.user_id else self.error
147
+ return self.user_id if self.user_id else "[ErioonClient] Unauthenticated"
188
148
 
189
149
  def __repr__(self):
190
- """
191
- Developer-friendly representation of the client.
192
- """
193
- return f"<ErioonClient user_id={self.user_id}>" if self.user_id else f"<ErioonClient error='{self.error}'>"
150
+ return f"<ErioonClient user_id={self.user_id}>" if self.user_id else "<ErioonClient unauthenticated>"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: erioon
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Erioon SDF for Python
5
5
  Author: Zyber Pireci
6
6
  Author-email: zyber.pireci@erioon.com
@@ -1,5 +1,5 @@
1
1
  erioon/auth.py,sha256=McktLrdxsWVyxhiFuk0qFokx63RI1yB8_qP3Mo7uZCI,724
2
- erioon/client.py,sha256=XUdktzV35uPq5dNAMXNN_1h3dva60p_qgJa-HOpzEOQ,6928
2
+ erioon/client.py,sha256=5Sd-s95UQokJLByA15ViYCxjAHennnb1vITj-nNtBKE,5714
3
3
  erioon/collection.py,sha256=EyNHpoOEBBMH29gMy51zzR338z2uI79kl0_ZB7laHpM,9700
4
4
  erioon/create.py,sha256=ilx0e3urK0lfYiaM3CSUe3Bf3l7GhHuwZyz0Z6ij0ok,10202
5
5
  erioon/database.py,sha256=hj5sgaEDXmItg4aeZlO3MP6_hV3jeS-d9qycEnw7xHQ,2449
@@ -8,8 +8,8 @@ erioon/functions.py,sha256=LWrqslAok-l9QlMEynT-Pvksy5hwkogWoeK5rJf464A,12479
8
8
  erioon/ping.py,sha256=BC0vZiane5YgCc07syZA5dKFcqbq1_Z8BUTmvIGRPcs,1829
9
9
  erioon/read.py,sha256=kzzqqRuLtYmlniAnkd2xeWNZm4AwMQ2oAMcpKt6JhcQ,10580
10
10
  erioon/update.py,sha256=E3d-dYJWh12bcAHx_vT9NFTscF__hViY3K9ZssN7At4,6060
11
- erioon-0.1.0.dist-info/LICENSE,sha256=xwnq3DNlZpQyteOK9HvtHRhMdYviXTTaCDljEodFRnQ,569
12
- erioon-0.1.0.dist-info/METADATA,sha256=cH2iOTgGtxzOLYNqcIN1T-YcNqaAxvq9ATlGBsFQAEQ,715
13
- erioon-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
- erioon-0.1.0.dist-info/top_level.txt,sha256=yjKEg85X5Q5ot46IMML_xukvIGG5YfdrLWcemjalItc,7
15
- erioon-0.1.0.dist-info/RECORD,,
11
+ erioon-0.1.2.dist-info/LICENSE,sha256=xwnq3DNlZpQyteOK9HvtHRhMdYviXTTaCDljEodFRnQ,569
12
+ erioon-0.1.2.dist-info/METADATA,sha256=IZzuMRl69uhU0QqDGhwa-iaLPALcwbhBlR7Pke0HlGU,715
13
+ erioon-0.1.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
+ erioon-0.1.2.dist-info/top_level.txt,sha256=yjKEg85X5Q5ot46IMML_xukvIGG5YfdrLWcemjalItc,7
15
+ erioon-0.1.2.dist-info/RECORD,,
File without changes