anzar 0.1.0__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.
anzar-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.3
2
+ Name: anzar
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author: Hakou Guelfen
6
+ Author-email: Hakou Guelfen <hakoudev@gmail.com>
7
+ Requires-Dist: dotenv>=0.9.9
8
+ Requires-Dist: keyring>=25.6.0
9
+ Requires-Dist: pydantic[email]>=2.11.7
10
+ Requires-Dist: requests>=2.32.5
11
+ Requires-Python: >=3.13
12
+ Description-Content-Type: text/markdown
13
+
14
+ # Anzar SDK Documentation
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install anzar
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```python
25
+ from anzar import AnzarAuth
26
+
27
+ # Initialize the SDK
28
+ auth = AnzarAuth
29
+
30
+ # Use the authenticated client
31
+ # (Add specific usage examples here)
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ ### Environment Variables
37
+
38
+ Create a `.env` file in your project root:
39
+
40
+ ```env
41
+ # Add your environment variables here
42
+ ANZAR_API_KEY=your_api_key
43
+ ANZAR_BASE_URL=https://api.anzar.com
44
+ ```
45
+
46
+ ## API Reference
47
+
48
+ ### AnzarAuth
49
+
50
+ Authentication manager for user login, registration, and session management.
51
+
52
+ ```python
53
+ from anzar import AnzarAuth
54
+ ```
55
+
56
+ #### Methods
57
+
58
+ ##### `login(email, password)`
59
+
60
+ Authenticate a user with credentials.
61
+
62
+ **Parameters:**
63
+ - `email` (str): User's email
64
+ - `password` (str): User's password
65
+
66
+ **Returns:**
67
+ - `User`: User object on success
68
+ - `Error`: Error object on failure
69
+
70
+ **Example:**
71
+ ```python
72
+ result = AnzarAuth.login("user@example.com", "password123")
73
+ if isinstance(result, User):
74
+ print(f"Logged in: {result.username}")
75
+ else:
76
+ print(f"Login failed: {result.error}")
77
+ ```
78
+
79
+ ##### `register(username, email, password)`
80
+
81
+ Register a new user account.
82
+
83
+ **Parameters:**
84
+ - `username` (str): Desired username
85
+ - `email` (str): User's email address
86
+ - `password` (str): User's password
87
+
88
+ **Returns:**
89
+ - `User`: User object on success
90
+ - `Error`: Error object on failure
91
+
92
+ **Example:**
93
+ ```python
94
+ result = AnzarAuth.register("newuser", "user@example.com", "password123")
95
+ ```
96
+
97
+ ##### `logout()`
98
+
99
+ Log out the current user.
100
+
101
+ **Returns:**
102
+ - `User`: Empty user object on success
103
+ - `Error`: Error object on failure
104
+
105
+ **Example:**
106
+ ```python
107
+ result = AnzarAuth.logout()
108
+ ```
109
+
110
+ ##### `isLoggedIn()`
111
+
112
+ Check if a user is currently logged in.
113
+
114
+ **Returns:**
115
+ - `User`: Current user object if logged in
116
+ - `Error`: Error object if not logged in
117
+
118
+ **Example:**
119
+ ```python
120
+ result = AnzarAuth.isLoggedIn()
121
+ if isinstance(result, User):
122
+ print(f"Current user: {result.username}")
123
+ else:
124
+ print("No user logged in")
125
+ ```
126
+
127
+ ## Error Handling
128
+
129
+ ```python
130
+ from anzar.types import Error
131
+ try:
132
+ result = AnzarAuth.login(email, password)
133
+ except Error as e:
134
+ print(f"Error: {e}")
135
+ ```
136
+
137
+ ## Examples
138
+
139
+ ### Basic Authentication Flow
140
+
141
+ ```python
142
+ from anzar import AnzarAuth
143
+
144
+ # Register new user
145
+ result = AnzarAuth.register("johndoe", "john@example.com", "securepass123")
146
+ if isinstance(result, Error):
147
+ print(f"Registration failed: {result.message}")
148
+ return
149
+
150
+ # Login
151
+ result = AnzarAuth.login("john@example.com", "securepass123")
152
+ if isinstance(result, Error):
153
+ print(f"Login failed: {result.message}")
154
+ return
155
+
156
+ print(f"Welcome {result.username}")
157
+
158
+ # Check login status
159
+ user = AnzarAuth.isLoggedIn()
160
+ if not isinstance(user, Error):
161
+ print(f"Current user: {user.username}")
162
+
163
+ # Logout
164
+ AnzarAuth.logout()
165
+ ```
166
+
167
+ ## Contributing
168
+
169
+ Instructions for contributing to the SDK.
170
+
171
+ ## License
172
+
173
+ License information.
anzar-0.1.0/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # Anzar SDK Documentation
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ pip install anzar
7
+ ```
8
+
9
+ ## Quick Start
10
+
11
+ ```python
12
+ from anzar import AnzarAuth
13
+
14
+ # Initialize the SDK
15
+ auth = AnzarAuth
16
+
17
+ # Use the authenticated client
18
+ # (Add specific usage examples here)
19
+ ```
20
+
21
+ ## Configuration
22
+
23
+ ### Environment Variables
24
+
25
+ Create a `.env` file in your project root:
26
+
27
+ ```env
28
+ # Add your environment variables here
29
+ ANZAR_API_KEY=your_api_key
30
+ ANZAR_BASE_URL=https://api.anzar.com
31
+ ```
32
+
33
+ ## API Reference
34
+
35
+ ### AnzarAuth
36
+
37
+ Authentication manager for user login, registration, and session management.
38
+
39
+ ```python
40
+ from anzar import AnzarAuth
41
+ ```
42
+
43
+ #### Methods
44
+
45
+ ##### `login(email, password)`
46
+
47
+ Authenticate a user with credentials.
48
+
49
+ **Parameters:**
50
+ - `email` (str): User's email
51
+ - `password` (str): User's password
52
+
53
+ **Returns:**
54
+ - `User`: User object on success
55
+ - `Error`: Error object on failure
56
+
57
+ **Example:**
58
+ ```python
59
+ result = AnzarAuth.login("user@example.com", "password123")
60
+ if isinstance(result, User):
61
+ print(f"Logged in: {result.username}")
62
+ else:
63
+ print(f"Login failed: {result.error}")
64
+ ```
65
+
66
+ ##### `register(username, email, password)`
67
+
68
+ Register a new user account.
69
+
70
+ **Parameters:**
71
+ - `username` (str): Desired username
72
+ - `email` (str): User's email address
73
+ - `password` (str): User's password
74
+
75
+ **Returns:**
76
+ - `User`: User object on success
77
+ - `Error`: Error object on failure
78
+
79
+ **Example:**
80
+ ```python
81
+ result = AnzarAuth.register("newuser", "user@example.com", "password123")
82
+ ```
83
+
84
+ ##### `logout()`
85
+
86
+ Log out the current user.
87
+
88
+ **Returns:**
89
+ - `User`: Empty user object on success
90
+ - `Error`: Error object on failure
91
+
92
+ **Example:**
93
+ ```python
94
+ result = AnzarAuth.logout()
95
+ ```
96
+
97
+ ##### `isLoggedIn()`
98
+
99
+ Check if a user is currently logged in.
100
+
101
+ **Returns:**
102
+ - `User`: Current user object if logged in
103
+ - `Error`: Error object if not logged in
104
+
105
+ **Example:**
106
+ ```python
107
+ result = AnzarAuth.isLoggedIn()
108
+ if isinstance(result, User):
109
+ print(f"Current user: {result.username}")
110
+ else:
111
+ print("No user logged in")
112
+ ```
113
+
114
+ ## Error Handling
115
+
116
+ ```python
117
+ from anzar.types import Error
118
+ try:
119
+ result = AnzarAuth.login(email, password)
120
+ except Error as e:
121
+ print(f"Error: {e}")
122
+ ```
123
+
124
+ ## Examples
125
+
126
+ ### Basic Authentication Flow
127
+
128
+ ```python
129
+ from anzar import AnzarAuth
130
+
131
+ # Register new user
132
+ result = AnzarAuth.register("johndoe", "john@example.com", "securepass123")
133
+ if isinstance(result, Error):
134
+ print(f"Registration failed: {result.message}")
135
+ return
136
+
137
+ # Login
138
+ result = AnzarAuth.login("john@example.com", "securepass123")
139
+ if isinstance(result, Error):
140
+ print(f"Login failed: {result.message}")
141
+ return
142
+
143
+ print(f"Welcome {result.username}")
144
+
145
+ # Check login status
146
+ user = AnzarAuth.isLoggedIn()
147
+ if not isinstance(user, Error):
148
+ print(f"Current user: {user.username}")
149
+
150
+ # Logout
151
+ AnzarAuth.logout()
152
+ ```
153
+
154
+ ## Contributing
155
+
156
+ Instructions for contributing to the SDK.
157
+
158
+ ## License
159
+
160
+ License information.
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "anzar"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Hakou Guelfen", email = "hakoudev@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.13"
10
+ dependencies = [
11
+ "dotenv>=0.9.9",
12
+ "keyring>=25.6.0",
13
+ "pydantic[email]>=2.11.7",
14
+ "requests>=2.32.5",
15
+ ]
16
+ # packages=["anzar", "anzar.types"]
17
+
18
+
19
+ [build-system]
20
+ requires = ["uv_build>=0.8.4,<0.9.0"]
21
+ build-backend = "uv_build"
22
+
23
+ [dependency-groups]
24
+ dev = []
25
+
26
+
27
+ [tool.uv]
28
+ dev-dependencies = [
29
+ "pytest",
30
+ ]
31
+
@@ -0,0 +1,21 @@
1
+ import dotenv
2
+ import logging
3
+
4
+ from ._api.client import HttpClient
5
+ from ._api.http_interceptor import HttpInterceptor
6
+
7
+ _ = dotenv.load_dotenv()
8
+
9
+ logging.basicConfig(
10
+ level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
11
+ )
12
+
13
+
14
+ def get_anzar_auth():
15
+ from ._auth.authenticator import AuthManager
16
+
17
+ return AuthManager(HttpClient(HttpInterceptor()))
18
+
19
+
20
+ AnzarAuth = get_anzar_auth()
21
+ __all__ = ["AnzarAuth"]
@@ -0,0 +1,37 @@
1
+ from requests.models import Response
2
+
3
+ from anzar._models.auth import LoginRequest, RegisterRequest
4
+ from anzar._api.http_interceptor import HttpInterceptor
5
+ from anzar._utils.errors import Error
6
+ from anzar._utils.types import T
7
+ from anzar._utils.validator import Validator
8
+
9
+
10
+ class HttpClient:
11
+ def __init__(self, http_interceptor: HttpInterceptor):
12
+ self.http_interceptor: HttpInterceptor = http_interceptor
13
+ self.accessToken: str | None = None
14
+
15
+ def get(self, url: str, model_type: type[T]) -> T | Error:
16
+ response: Response = self.http_interceptor.get(url)
17
+
18
+ if response.status_code in (200, 201):
19
+ return model_type.model_validate(response.json())
20
+ else:
21
+ return Error.model_validate(response.json())
22
+
23
+ def post(
24
+ self,
25
+ url: str,
26
+ data: LoginRequest | RegisterRequest | None,
27
+ model_type: type[T],
28
+ ) -> T | Error:
29
+ if data:
30
+ response: Response = self.http_interceptor.post(url, json=data.__dict__)
31
+ else:
32
+ response = self.http_interceptor.post(url)
33
+
34
+ if response.status_code in (200, 201):
35
+ return Validator().validate(model_type, response)
36
+ else:
37
+ return Error.model_validate(response.json())
@@ -0,0 +1,113 @@
1
+ import logging
2
+ import os
3
+ from typing import Any, override
4
+
5
+ import requests
6
+ from requests.adapters import HTTPAdapter
7
+ from urllib3.util import Retry
8
+
9
+ from anzar._models.auth import AuthResponse, JWTTokens
10
+ from anzar._utils.config import Config
11
+ from anzar._utils.storage import TokenStorage
12
+ from anzar._utils.types import Token, TokenType
13
+
14
+
15
+ class HttpInterceptor(requests.Session):
16
+ def __init__(self) -> None:
17
+ super().__init__()
18
+ self.API_URL: str = os.getenv("API_URL", "http://localhost:3000")
19
+ self.storage: TokenStorage = TokenStorage()
20
+ self.banned_endpoints: list[str] = ["auth/login", "auth/register"]
21
+ self.refresh_endpoints: list[str] = ["auth/logout", "auth/refreshToken"]
22
+
23
+ # Retry logic (optional)
24
+ retries = Retry(
25
+ total=3,
26
+ backoff_factor=1,
27
+ status_forcelist=[500, 502, 503, 504],
28
+ allowed_methods=["GET", "POST", "PUT", "DELETE", "PATCH"],
29
+ )
30
+ adapter = HTTPAdapter(max_retries=retries)
31
+ self.mount("http://", adapter)
32
+ self.mount("https://", adapter)
33
+
34
+ def __extractTokenFromCache(self, tokenType: TokenType) -> Token | None:
35
+ token = self.storage.load(tokenType.name)
36
+ return Token.new(token, tokenType) if token else None
37
+
38
+ def __isUrlPartOf(self, url: str | bytes, endpoints: list[str]) -> bool:
39
+ for endpoint in endpoints:
40
+ if url == f"{self.API_URL}/{endpoint}":
41
+ return True
42
+ return False
43
+
44
+ def __get_appropriate_token(self, url: str | bytes) -> Token | None:
45
+ if self.__isUrlPartOf(url, self.banned_endpoints):
46
+ return None
47
+
48
+ if self.__isUrlPartOf(url, self.refresh_endpoints):
49
+ return self.__extractTokenFromCache(TokenType.RefreshToken)
50
+
51
+ return self.__extractTokenFromCache(TokenType.AccessToken)
52
+
53
+ def __handle_auth_response(
54
+ self, url: str | bytes, response: requests.Response
55
+ ) -> None:
56
+ if not response.ok:
57
+ return
58
+
59
+ if url == f"{self.API_URL}/auth/refreshToken":
60
+ jwtTokens = JWTTokens.model_validate(response.json())
61
+ elif self.__isUrlPartOf(url, self.banned_endpoints):
62
+ auth_response = AuthResponse.model_validate(response.json())
63
+ jwtTokens = JWTTokens(
64
+ accessToken=auth_response.accessToken,
65
+ refreshToken=auth_response.refreshToken,
66
+ )
67
+ else:
68
+ return
69
+
70
+ self.storage.save(jwtTokens)
71
+
72
+ def __send_request(
73
+ self, method: str | bytes, url: str | bytes, *args, **kwargs
74
+ ) -> requests.Response:
75
+ token = self.__get_appropriate_token(url)
76
+ kwargs["headers"] = Config().headers(token=token)
77
+ return super().request(method, url, timeout=30, *args, **kwargs)
78
+
79
+ @override
80
+ def request(
81
+ self,
82
+ method: str | bytes,
83
+ url: str | bytes,
84
+ _refresh_attempted: bool = False,
85
+ *args: Any,
86
+ **kwargs: Any,
87
+ ) -> requests.Response:
88
+ # PRE-REQUEST INTERCEPTION
89
+ logging.info(f"{method} {url}")
90
+ response = self.__send_request(method, url, *args, **kwargs)
91
+
92
+ # POST-RESPONSE INTERCEPTION
93
+ logging.info(f"Response: {response.status_code}")
94
+ if (
95
+ response.status_code == 401
96
+ and not self.__isUrlPartOf(url, self.banned_endpoints)
97
+ and not self.__isUrlPartOf(url, self.refresh_endpoints)
98
+ and not _refresh_attempted
99
+ ):
100
+ # header: Content-Type: application/x-www-form-urlencoded
101
+ response = self.request(
102
+ method="POST",
103
+ url=f"{self.API_URL}/auth/refreshToken",
104
+ _refresh_attempted=True,
105
+ *args,
106
+ **kwargs,
107
+ )
108
+
109
+ response = self.__send_request(method, url, *args, **kwargs)
110
+
111
+ self.__handle_auth_response(url, response)
112
+
113
+ return response
@@ -0,0 +1,81 @@
1
+ import os
2
+
3
+ from anzar._api.client import HttpClient
4
+
5
+ from anzar._models.auth import AuthResponse
6
+ from anzar._models.user import User
7
+ from anzar._utils.errors import Error
8
+ from anzar._utils.storage import TokenStorage
9
+ from anzar._utils.types import NoType
10
+ from anzar._utils.validator import Validator
11
+
12
+
13
+ class AuthManager:
14
+ def __init__(self, httpClient: HttpClient) -> None:
15
+ self._http_client: HttpClient = httpClient
16
+
17
+ self._API_URL: str = os.getenv("API_URL", "http://localhost:3000")
18
+ assert self._API_URL is not None, "Env was unable to load"
19
+ self.__endpoints: dict[str, str] = {
20
+ "login": f"{self._API_URL}/auth/login",
21
+ "register": f"{self._API_URL}/auth/register",
22
+ "user": f"{self._API_URL}/user",
23
+ "logout": f"{self._API_URL}/auth/logout",
24
+ }
25
+
26
+ def register(self, username: str, email: str, password: str) -> Error | User:
27
+ req = Validator().construct_register(username, email, password)
28
+ if isinstance(req, Error):
29
+ return req
30
+
31
+ url = self.__endpoints["register"]
32
+ response = self._http_client.post(url, req, AuthResponse)
33
+
34
+ return response.user if isinstance(response, AuthResponse) else response
35
+
36
+ def login(self, email: str, password: str):
37
+ req = Validator().construct_login(email, password)
38
+ if isinstance(req, Error):
39
+ return req
40
+
41
+ url = self.__endpoints["login"]
42
+ response = self._http_client.post(url, req, AuthResponse)
43
+
44
+ return response.user if isinstance(response, AuthResponse) else response
45
+
46
+ def getUser(self):
47
+ url = self.__endpoints["user"]
48
+ response = self._http_client.get(url, User)
49
+ return response
50
+
51
+ def logout(self):
52
+ url = self.__endpoints["logout"]
53
+ response = self._http_client.post(url, None, NoType)
54
+ TokenStorage().clear()
55
+
56
+ return response
57
+
58
+
59
+ # def main():
60
+ # from pprint import pprint
61
+ # from anzar._api.http_interceptor import HttpInterceptor
62
+ #
63
+ # authManager = AuthManager(HttpClient(HttpInterceptor()))
64
+ #
65
+ # # username, email, password = "Hakou", "hakouguelfen@gmail.com", "hakouguelfen"
66
+ # # user = authManager.register(username, email, password)
67
+ # # pprint(user)
68
+ #
69
+ # # email, password = "hakouguelfen@gmail.com", "hakouguelfen"
70
+ # # user = authManager.login(email, password)
71
+ # # pprint(user)
72
+ #
73
+ # user = authManager.getUser()
74
+ # pprint(user)
75
+ #
76
+ # response = authManager.logout()
77
+ # pprint(response)
78
+ #
79
+ #
80
+ # if __name__ == "__main__":
81
+ # main()
File without changes
@@ -0,0 +1,29 @@
1
+ from pydantic import BaseModel, EmailStr
2
+ from pydantic.dataclasses import dataclass
3
+
4
+ from .user import User
5
+
6
+
7
+ @dataclass()
8
+ class LoginRequest:
9
+ email: EmailStr
10
+ password: str
11
+
12
+
13
+ @dataclass()
14
+ class RegisterRequest:
15
+ username: str
16
+ email: EmailStr
17
+ password: str
18
+
19
+
20
+ class AuthResponse(BaseModel):
21
+ accessToken: str
22
+ refreshToken: str
23
+ user: User
24
+
25
+
26
+ class JWTTokens(BaseModel):
27
+ accessToken: str
28
+ refreshToken: str
29
+ refreshTokenJti: str | None = None
@@ -0,0 +1,18 @@
1
+ from pydantic import BaseModel, EmailStr
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class Role(str, Enum):
7
+ Admin = "Admin"
8
+ User = "User"
9
+
10
+
11
+ class User(BaseModel):
12
+ # id: str | None = Field(None, alias="_id")
13
+ _id: str | None
14
+ username: str
15
+ email: EmailStr
16
+ role: Role
17
+ isPremium: bool
18
+ accountLocked: bool
@@ -0,0 +1,16 @@
1
+ from anzar._utils.types import Header, Token, TokenType
2
+
3
+
4
+ class Config:
5
+ def headers(self, token: Token | None) -> Header:
6
+ default_headers = {
7
+ "Content-Type": "application/json",
8
+ "User-Agent": "Anzar-SDK/1.0",
9
+ }
10
+ if token is not None:
11
+ if token.tokenType == TokenType.AccessToken:
12
+ default_headers["authorization"] = f"Bearer {token.value}"
13
+ if token.tokenType == TokenType.RefreshToken:
14
+ default_headers["x-refresh-token"] = f"Bearer {token.value}"
15
+
16
+ return default_headers
@@ -0,0 +1,5 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class Error(BaseModel):
5
+ error: str
@@ -0,0 +1,29 @@
1
+ import keyring
2
+
3
+ from anzar._models.auth import JWTTokens
4
+ from anzar._utils.types import TokenType
5
+
6
+
7
+ SERVICE_NAME = "AnzarSDK"
8
+
9
+ ACCESS_TOKEN = TokenType.AccessToken.name
10
+ REFRESH_TOKEN = TokenType.RefreshToken.name
11
+
12
+
13
+ class TokenStorage:
14
+ def save(self, tokens: JWTTokens):
15
+ try:
16
+ keyring.set_password(SERVICE_NAME, ACCESS_TOKEN, tokens.accessToken)
17
+ keyring.set_password(SERVICE_NAME, REFRESH_TOKEN, tokens.refreshToken)
18
+ except Exception as e:
19
+ print(e)
20
+
21
+ def load(self, username: str):
22
+ try:
23
+ return keyring.get_password(SERVICE_NAME, username)
24
+ except Exception as e:
25
+ print(e)
26
+
27
+ def clear(self):
28
+ keyring.set_password(SERVICE_NAME, ACCESS_TOKEN, "")
29
+ keyring.set_password(SERVICE_NAME, REFRESH_TOKEN, "")
@@ -0,0 +1,68 @@
1
+ from collections.abc import Mapping
2
+ from dataclasses import dataclass
3
+ from enum import Enum, auto
4
+ from typing import Generic, TypeVar, override
5
+
6
+ from pydantic import BaseModel
7
+
8
+ Header = Mapping[str, str | bytes | None]
9
+ T = TypeVar("T", bound=BaseModel)
10
+
11
+
12
+ class NoType(BaseModel):
13
+ status: str | None
14
+
15
+
16
+ class TokenType(Enum):
17
+ AccessToken = auto()
18
+ RefreshToken = auto()
19
+
20
+
21
+ @dataclass()
22
+ class Token:
23
+ value: str
24
+ tokenType: TokenType
25
+
26
+ @classmethod
27
+ def new(cls, value: str, tokenType: TokenType):
28
+ return cls(value, tokenType)
29
+
30
+
31
+ R = TypeVar("R")
32
+
33
+
34
+ class Result(Generic[R]):
35
+ @property
36
+ def is_ok(self) -> bool: ...
37
+ @property
38
+ def is_err(self) -> bool: ...
39
+
40
+
41
+ class Ok(Result[R]):
42
+ def __init__(self, value: R) -> None:
43
+ self.value: R = value
44
+
45
+ @property
46
+ @override
47
+ def is_ok(self) -> bool:
48
+ return True
49
+
50
+ @property
51
+ @override
52
+ def is_err(self) -> bool:
53
+ return False
54
+
55
+
56
+ class Err(Result[R]):
57
+ def __init__(self, error: str) -> None:
58
+ self.error: str = error
59
+
60
+ @property
61
+ @override
62
+ def is_ok(self) -> bool:
63
+ return False
64
+
65
+ @property
66
+ @override
67
+ def is_err(self) -> bool:
68
+ return True
@@ -0,0 +1,36 @@
1
+ from pydantic import ValidationError
2
+ from requests import Response
3
+
4
+ from anzar._utils.errors import Error
5
+ from anzar._utils.types import T
6
+
7
+ from anzar._models.auth import LoginRequest, RegisterRequest
8
+
9
+
10
+ class Validator:
11
+ def construct_register(
12
+ self, username: str, email: str, password: str
13
+ ) -> RegisterRequest | Error:
14
+ try:
15
+ return RegisterRequest(username, email, password)
16
+
17
+ except ValidationError as e:
18
+ ctx = e.errors()[0].get("ctx")
19
+
20
+ reason: str | None = ctx.get("reason") if ctx else None
21
+ return Error(error=reason or "Data is not validated")
22
+
23
+ def construct_login(self, email: str, password: str) -> LoginRequest | Error:
24
+ try:
25
+ return LoginRequest(email, password)
26
+ except ValidationError as e:
27
+ ctx = e.errors()[0].get("ctx")
28
+
29
+ reason: str | None = ctx.get("reason") if ctx else None
30
+ return Error(error=reason or "Data is not validated")
31
+
32
+ def validate(self, model_type: type[T], res: Response) -> T | Error:
33
+ try:
34
+ return model_type.model_validate(res.json())
35
+ except ValidationError as _:
36
+ return Error(error="")
File without changes
@@ -0,0 +1,8 @@
1
+ from ._utils.errors import Error
2
+ from ._utils.types import NoType
3
+
4
+ from anzar._models.user import User
5
+ from anzar._models.auth import AuthResponse
6
+
7
+
8
+ __all__ = ["User", "AuthResponse", "NoType", "Error"]