ai-parrot 0.8.3__cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.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.
Potentially problematic release.
This version of ai-parrot might be problematic. Click here for more details.
- ai_parrot-0.8.3.dist-info/LICENSE +21 -0
- ai_parrot-0.8.3.dist-info/METADATA +306 -0
- ai_parrot-0.8.3.dist-info/RECORD +128 -0
- ai_parrot-0.8.3.dist-info/WHEEL +6 -0
- ai_parrot-0.8.3.dist-info/top_level.txt +2 -0
- parrot/__init__.py +30 -0
- parrot/bots/__init__.py +5 -0
- parrot/bots/abstract.py +1115 -0
- parrot/bots/agent.py +492 -0
- parrot/bots/basic.py +9 -0
- parrot/bots/bose.py +17 -0
- parrot/bots/chatbot.py +271 -0
- parrot/bots/cody.py +17 -0
- parrot/bots/copilot.py +117 -0
- parrot/bots/data.py +730 -0
- parrot/bots/dataframe.py +103 -0
- parrot/bots/hrbot.py +15 -0
- parrot/bots/interfaces/__init__.py +1 -0
- parrot/bots/interfaces/retrievers.py +12 -0
- parrot/bots/notebook.py +619 -0
- parrot/bots/odoo.py +17 -0
- parrot/bots/prompts/__init__.py +41 -0
- parrot/bots/prompts/agents.py +91 -0
- parrot/bots/prompts/data.py +214 -0
- parrot/bots/retrievals/__init__.py +1 -0
- parrot/bots/retrievals/constitutional.py +19 -0
- parrot/bots/retrievals/multi.py +122 -0
- parrot/bots/retrievals/retrieval.py +610 -0
- parrot/bots/tools/__init__.py +7 -0
- parrot/bots/tools/eda.py +325 -0
- parrot/bots/tools/pdf.py +50 -0
- parrot/bots/tools/plot.py +48 -0
- parrot/bots/troc.py +16 -0
- parrot/conf.py +170 -0
- parrot/crew/__init__.py +3 -0
- parrot/crew/tools/__init__.py +22 -0
- parrot/crew/tools/bing.py +13 -0
- parrot/crew/tools/config.py +43 -0
- parrot/crew/tools/duckgo.py +62 -0
- parrot/crew/tools/file.py +24 -0
- parrot/crew/tools/google.py +168 -0
- parrot/crew/tools/gtrends.py +16 -0
- parrot/crew/tools/md2pdf.py +25 -0
- parrot/crew/tools/rag.py +42 -0
- parrot/crew/tools/search.py +32 -0
- parrot/crew/tools/url.py +21 -0
- parrot/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/handlers/__init__.py +4 -0
- parrot/handlers/agents.py +292 -0
- parrot/handlers/bots.py +196 -0
- parrot/handlers/chat.py +192 -0
- parrot/interfaces/__init__.py +6 -0
- parrot/interfaces/database.py +27 -0
- parrot/interfaces/http.py +805 -0
- parrot/interfaces/images/__init__.py +0 -0
- parrot/interfaces/images/plugins/__init__.py +18 -0
- parrot/interfaces/images/plugins/abstract.py +58 -0
- parrot/interfaces/images/plugins/exif.py +709 -0
- parrot/interfaces/images/plugins/hash.py +52 -0
- parrot/interfaces/images/plugins/vision.py +104 -0
- parrot/interfaces/images/plugins/yolo.py +66 -0
- parrot/interfaces/images/plugins/zerodetect.py +197 -0
- parrot/llms/__init__.py +1 -0
- parrot/llms/abstract.py +69 -0
- parrot/llms/anthropic.py +58 -0
- parrot/llms/gemma.py +15 -0
- parrot/llms/google.py +44 -0
- parrot/llms/groq.py +67 -0
- parrot/llms/hf.py +45 -0
- parrot/llms/openai.py +61 -0
- parrot/llms/pipes.py +114 -0
- parrot/llms/vertex.py +89 -0
- parrot/loaders/__init__.py +9 -0
- parrot/loaders/abstract.py +628 -0
- parrot/loaders/files/__init__.py +0 -0
- parrot/loaders/files/abstract.py +39 -0
- parrot/loaders/files/text.py +63 -0
- parrot/loaders/txt.py +26 -0
- parrot/manager.py +333 -0
- parrot/models.py +504 -0
- parrot/py.typed +0 -0
- parrot/stores/__init__.py +11 -0
- parrot/stores/abstract.py +248 -0
- parrot/stores/chroma.py +188 -0
- parrot/stores/duck.py +162 -0
- parrot/stores/embeddings/__init__.py +10 -0
- parrot/stores/embeddings/abstract.py +46 -0
- parrot/stores/embeddings/base.py +52 -0
- parrot/stores/embeddings/bge.py +20 -0
- parrot/stores/embeddings/fastembed.py +17 -0
- parrot/stores/embeddings/google.py +18 -0
- parrot/stores/embeddings/huggingface.py +20 -0
- parrot/stores/embeddings/ollama.py +14 -0
- parrot/stores/embeddings/openai.py +26 -0
- parrot/stores/embeddings/transformers.py +21 -0
- parrot/stores/embeddings/vertexai.py +17 -0
- parrot/stores/empty.py +10 -0
- parrot/stores/faiss.py +160 -0
- parrot/stores/milvus.py +397 -0
- parrot/stores/postgres.py +653 -0
- parrot/stores/qdrant.py +170 -0
- parrot/tools/__init__.py +23 -0
- parrot/tools/abstract.py +68 -0
- parrot/tools/asknews.py +33 -0
- parrot/tools/basic.py +51 -0
- parrot/tools/bby.py +359 -0
- parrot/tools/bing.py +13 -0
- parrot/tools/docx.py +343 -0
- parrot/tools/duck.py +62 -0
- parrot/tools/execute.py +56 -0
- parrot/tools/gamma.py +28 -0
- parrot/tools/google.py +170 -0
- parrot/tools/gvoice.py +301 -0
- parrot/tools/results.py +278 -0
- parrot/tools/stack.py +27 -0
- parrot/tools/weather.py +70 -0
- parrot/tools/wikipedia.py +58 -0
- parrot/tools/zipcode.py +198 -0
- parrot/utils/__init__.py +2 -0
- parrot/utils/parsers/__init__.py +5 -0
- parrot/utils/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/toml.py +11 -0
- parrot/utils/types.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/uv.py +11 -0
- parrot/version.py +10 -0
- resources/users/__init__.py +5 -0
- resources/users/handlers.py +13 -0
- resources/users/models.py +205 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Optional, Any
|
|
2
|
+
from langchain_core.callbacks import CallbackManagerForToolRun
|
|
3
|
+
from langchain_community.tools import WikipediaQueryRun
|
|
4
|
+
from langchain_community.utilities import WikipediaAPIWrapper
|
|
5
|
+
from langchain_community.tools.wikidata.tool import WikidataAPIWrapper, WikidataQueryRun
|
|
6
|
+
from langchain.tools import BaseTool
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WikipediaTool(BaseTool):
|
|
10
|
+
"""Tool that searches the Wikipedia API."""
|
|
11
|
+
name = "Wikipedia"
|
|
12
|
+
description: str = (
|
|
13
|
+
"Access detailed and verified information from Wikipedia. "
|
|
14
|
+
"Useful for searching Wikipedia for general information. "
|
|
15
|
+
"Useful for when you need to answer general questions about "
|
|
16
|
+
"people, places, companies, facts, historical events, or other subjects. "
|
|
17
|
+
"Input should be a search query."
|
|
18
|
+
)
|
|
19
|
+
search: Any = None
|
|
20
|
+
|
|
21
|
+
def __init__(self, **kwargs):
|
|
22
|
+
super().__init__(**kwargs)
|
|
23
|
+
self.search = WikipediaQueryRun(
|
|
24
|
+
api_wrapper=WikipediaAPIWrapper()
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def _run(
|
|
28
|
+
self,
|
|
29
|
+
query: str,
|
|
30
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
31
|
+
) -> str:
|
|
32
|
+
"""Use the Wikipedia tool."""
|
|
33
|
+
return self.search.run(query)
|
|
34
|
+
|
|
35
|
+
class WikidataTool(BaseTool):
|
|
36
|
+
"""Tool that searches the Wikidata API."""
|
|
37
|
+
name: str = "Wikidata"
|
|
38
|
+
description: str = (
|
|
39
|
+
"Fetch structured data from WikiData for precise and factual details. "
|
|
40
|
+
"Useful for when you need to answer general questions about "
|
|
41
|
+
"people, places, companies, facts, historical events, or other subjects. "
|
|
42
|
+
"Input should be the exact name of the item you want information about or a Wikidata QID."
|
|
43
|
+
)
|
|
44
|
+
search: Any = None
|
|
45
|
+
|
|
46
|
+
def __init__(self, **kwargs):
|
|
47
|
+
super().__init__(**kwargs)
|
|
48
|
+
self.search = WikidataQueryRun(
|
|
49
|
+
api_wrapper=WikidataAPIWrapper()
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def _run(
|
|
53
|
+
self,
|
|
54
|
+
query: str,
|
|
55
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
56
|
+
) -> str:
|
|
57
|
+
"""Use the Wikidata tool."""
|
|
58
|
+
return self.search.run(query)
|
parrot/tools/zipcode.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Optional, Type, Union
|
|
2
|
+
import httpx
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from langchain_core.callbacks import CallbackManagerForToolRun
|
|
5
|
+
from langchain_core.tools import BaseToolkit
|
|
6
|
+
from langchain_core.tools import BaseTool
|
|
7
|
+
from navconfig import config
|
|
8
|
+
from .abstract import AbstractTool
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ZipcodeDistanceInput(BaseModel):
|
|
12
|
+
"""Input for the Zipcode Distance Tool."""
|
|
13
|
+
zipcode1: Union[str, int] = Field(description="The first zipcode.")
|
|
14
|
+
zipcode2: Union[str, int] = Field(description="The second zipcode.")
|
|
15
|
+
unit: Optional[str] = Field(description="The unit of the distance.", default="mile")
|
|
16
|
+
|
|
17
|
+
model_config = {
|
|
18
|
+
"arbitrary_types_allowed": True,
|
|
19
|
+
"extra": "forbid", # Helps with compatibility
|
|
20
|
+
"json_schema_extra": {
|
|
21
|
+
"required": ["zipcode", "sku", "location_id"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class ZipcodeRadiusInput(BaseModel):
|
|
26
|
+
"""Input for the Zipcode Radius Tool."""
|
|
27
|
+
zipcode: Union[str, int] = Field(description="The zipcode.")
|
|
28
|
+
radius: int = Field(description="The radius in miles.", default=5)
|
|
29
|
+
unit: Optional[str] = Field(description="The unit of the distance.", default="mile")
|
|
30
|
+
|
|
31
|
+
model_config = {
|
|
32
|
+
"arbitrary_types_allowed": True,
|
|
33
|
+
"extra": "forbid", # Helps with compatibility
|
|
34
|
+
"json_schema_extra": {
|
|
35
|
+
"required": ["zipcode", "sku", "location_id"]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class ZipcodeLocationInput(BaseModel):
|
|
40
|
+
"""Input for the Zipcode Location Tool."""
|
|
41
|
+
zipcode: Union[str, int] = Field(description="The zipcode.")
|
|
42
|
+
unit: Optional[str] = Field(description="The unit of the distance.", default="degrees")
|
|
43
|
+
|
|
44
|
+
model_config = {
|
|
45
|
+
"arbitrary_types_allowed": True,
|
|
46
|
+
"extra": "forbid", # Helps with compatibility
|
|
47
|
+
"json_schema_extra": {
|
|
48
|
+
"required": ["zipcode", "sku", "location_id"]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class ZipcodeDistance(AbstractTool):
|
|
53
|
+
"""Tool for calculating the distance between two zipcodes."""
|
|
54
|
+
|
|
55
|
+
name: str = "zipcode_distance"
|
|
56
|
+
verbose: bool = True
|
|
57
|
+
args_schema: Type[BaseModel] = ZipcodeDistanceInput
|
|
58
|
+
description: str = (
|
|
59
|
+
"Use this tool to calculate the distance between two zipcodes."
|
|
60
|
+
" Zipcodes must be provided as a couple of strings (e.g., '33066')."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
model_config = {
|
|
64
|
+
"arbitrary_types_allowed": True,
|
|
65
|
+
"extra": "forbid", # Helps with compatibility
|
|
66
|
+
"json_schema_extra": {
|
|
67
|
+
"required": ["zipcode", "sku", "location_id"]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
def _search(
|
|
72
|
+
self,
|
|
73
|
+
zipcode1: str,
|
|
74
|
+
zipcode2: str,
|
|
75
|
+
unit: Optional[str] = 'mile',
|
|
76
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
77
|
+
) -> Dict[str, Any]: # Changed to Dict
|
|
78
|
+
api_key = config.get('ZIPCODE_API_KEY')
|
|
79
|
+
url = f"https://www.zipcodeapi.com/rest/{api_key}/distance.json/{zipcode1}/{zipcode2}/{unit}"
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
response = httpx.get(url)
|
|
83
|
+
response.raise_for_status() # Check for API errors
|
|
84
|
+
return response.json()
|
|
85
|
+
except httpx.HTTPStatusError as e:
|
|
86
|
+
raise ValueError(f"Error fetching zipcode distance: {e}") from e
|
|
87
|
+
|
|
88
|
+
async def _asearch(
|
|
89
|
+
self,
|
|
90
|
+
zipcode1: str,
|
|
91
|
+
zipcode2: str,
|
|
92
|
+
unit: Optional[str] = 'mile',
|
|
93
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
94
|
+
) -> Dict[str, Any]:
|
|
95
|
+
api_key = config.get('ZIPCODE_API_KEY')
|
|
96
|
+
url = f"https://www.zipcodeapi.com/rest/{api_key}/distance.json/{zipcode1}/{zipcode2}/{unit}"
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
async with httpx.AsyncClient() as client:
|
|
100
|
+
response = await client.get(url)
|
|
101
|
+
response.raise_for_status() # Check for API errors
|
|
102
|
+
return response.json()
|
|
103
|
+
except httpx.HTTPStatusError as e:
|
|
104
|
+
raise ValueError(f"Error fetching zipcode distance: {e}") from e
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class ZipcodeRadius(AbstractTool):
|
|
108
|
+
"""Tool for calculating the distance between two zipcodes."""
|
|
109
|
+
|
|
110
|
+
name: str = "zipcodes_by_radius"
|
|
111
|
+
verbose: bool = True
|
|
112
|
+
args_schema: Type[BaseModel] = ZipcodeRadiusInput
|
|
113
|
+
description: str = (
|
|
114
|
+
"Use this Tool to find all US zip codes within a given radius of a zip code."
|
|
115
|
+
" Provides a Zipcode and a radius."
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
model_config = {
|
|
119
|
+
"arbitrary_types_allowed": True,
|
|
120
|
+
"extra": "forbid", # Helps with compatibility
|
|
121
|
+
"json_schema_extra": {
|
|
122
|
+
"required": ["zipcode", "sku", "location_id"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def _search(
|
|
127
|
+
self,
|
|
128
|
+
zipcode: Union[str, int],
|
|
129
|
+
radius: int = 5,
|
|
130
|
+
unit: Optional[str] = 'mile',
|
|
131
|
+
) -> Dict[str, Any]: # Changed to Dict
|
|
132
|
+
api_key = config.get('ZIPCODE_API_KEY')
|
|
133
|
+
url = f"https://www.zipcodeapi.com/rest/{api_key}/radius.json/{zipcode}/{radius}/{unit}"
|
|
134
|
+
try:
|
|
135
|
+
response = httpx.get(url)
|
|
136
|
+
response.raise_for_status() # Check for API errors
|
|
137
|
+
return response.json()
|
|
138
|
+
except httpx.HTTPStatusError as e:
|
|
139
|
+
raise ValueError(f"Error fetching zipcode distance: {e}") from e
|
|
140
|
+
|
|
141
|
+
async def _asearch(
|
|
142
|
+
self,
|
|
143
|
+
zipcode: str,
|
|
144
|
+
radius: int,
|
|
145
|
+
unit: Optional[str] = 'mile'
|
|
146
|
+
) -> Dict[str, Any]:
|
|
147
|
+
api_key = config.get('ZIPCODE_API_KEY')
|
|
148
|
+
url = f"https://www.zipcodeapi.com/rest/{api_key}/radius.json/{zipcode}/{radius}/{unit}"
|
|
149
|
+
|
|
150
|
+
try:
|
|
151
|
+
async with httpx.AsyncClient() as client:
|
|
152
|
+
response = await client.get(url)
|
|
153
|
+
response.raise_for_status() # Check for API errors
|
|
154
|
+
return response.json()
|
|
155
|
+
except httpx.HTTPStatusError as e:
|
|
156
|
+
raise ValueError(f"Error fetching zipcode distance: {e}") from e
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class ZipcodeLocation(AbstractTool):
|
|
161
|
+
"""Tool for calculating Geographical information about a Zipcode."""
|
|
162
|
+
|
|
163
|
+
name: str = "zipcode_location"
|
|
164
|
+
verbose: bool = True
|
|
165
|
+
args_schema: Type[BaseModel] = ZipcodeLocationInput
|
|
166
|
+
description: str = (
|
|
167
|
+
"Use this Tool to find out the city, state, latitude, longitude, and time zone information for a US zip code."
|
|
168
|
+
" Use this tool to find geographical information about a zipcode. "
|
|
169
|
+
" Provides only a Zipcode as string."
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def _search(
|
|
173
|
+
self,
|
|
174
|
+
zipcode: str,
|
|
175
|
+
unit: Optional[str] = 'degrees'
|
|
176
|
+
) -> Dict[str, Any]: # Changed to Dict
|
|
177
|
+
api_key = config.get('ZIPCODE_API_KEY')
|
|
178
|
+
url = f"https://www.zipcodeapi.com/rest/{api_key}/info.json/{zipcode}/{unit}"
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
response = httpx.get(url)
|
|
182
|
+
response.raise_for_status() # Check for API errors
|
|
183
|
+
return response.json()
|
|
184
|
+
except httpx.HTTPStatusError as e:
|
|
185
|
+
raise ValueError(f"Error fetching zipcode distance: {e}") from e
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class ZipcodeAPIToolkit(BaseToolkit):
|
|
189
|
+
"""Toolkit for interacting with ZipcodeAPI.
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
def get_tools(self) -> List[BaseTool]:
|
|
193
|
+
"""Get the tools in the toolkit."""
|
|
194
|
+
return [
|
|
195
|
+
ZipcodeLocation(),
|
|
196
|
+
ZipcodeRadius(),
|
|
197
|
+
ZipcodeDistance()
|
|
198
|
+
]
|
parrot/utils/__init__.py
ADDED
|
Binary file
|
parrot/utils/toml.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .parsers import TOMLParser
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
async def parse_toml_config(config_dir: str) -> dict:
|
|
5
|
+
try:
|
|
6
|
+
parser = TOMLParser()
|
|
7
|
+
return await parser.parse(config_dir)
|
|
8
|
+
except Exception as exc:
|
|
9
|
+
raise ValueError(
|
|
10
|
+
f"Error Parsing TOML Config on {config_dir}: {exc}"
|
|
11
|
+
)
|
|
Binary file
|
parrot/utils/uv.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def install_uvloop():
|
|
5
|
+
"""install uvloop and set as default loop for asyncio."""
|
|
6
|
+
try:
|
|
7
|
+
import uvloop # noqa # pylint: disable=import-outside-toplevel
|
|
8
|
+
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
9
|
+
uvloop.install()
|
|
10
|
+
except ImportError:
|
|
11
|
+
pass
|
parrot/version.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Nav Parrot Meta information."""
|
|
2
|
+
|
|
3
|
+
__title__ = "ai-parrot"
|
|
4
|
+
__description__ = "Live Chatbots based on Langchain chatbots and Agents \
|
|
5
|
+
Integrated into Navigator Framework or used into any aiohttp applications."
|
|
6
|
+
__version__ = "0.8.3"
|
|
7
|
+
__author__ = "Jesus Lara"
|
|
8
|
+
__author_email__ = "jesuslarag@gmail.com"
|
|
9
|
+
__license__ = "MIT"
|
|
10
|
+
__copyright__ = 'Copyright (c) 2020-2024 Jesus Lara'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from datamodel import BaseModel
|
|
2
|
+
from navigator.views import ModelView
|
|
3
|
+
from .models import ADUser, ADPeople
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ADUserHandler(ModelView):
|
|
7
|
+
model: BaseModel = ADUser
|
|
8
|
+
pk: str = 'people_id'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ADPeopleHandler(ModelView):
|
|
12
|
+
model: BaseModel = ADPeople
|
|
13
|
+
pk: str = 'people_id'
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
from typing import Optional, List
|
|
2
|
+
from datetime import datetime, timedelta
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
from datamodel.types import Text
|
|
5
|
+
from asyncdb.models import Column, Model
|
|
6
|
+
from navigator_auth.conf import AUTH_DB_SCHEMA, AUTH_USERS_VIEW
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class User(Model):
|
|
10
|
+
"""Basic User notation."""
|
|
11
|
+
|
|
12
|
+
user_id: int = Column(
|
|
13
|
+
required=False,
|
|
14
|
+
primary_key=True,
|
|
15
|
+
db_default="auto"
|
|
16
|
+
)
|
|
17
|
+
first_name: str
|
|
18
|
+
last_name: str
|
|
19
|
+
display_name: str
|
|
20
|
+
email: str = Column(required=False, max=254)
|
|
21
|
+
alt_email: str = Column(required=False, max=254)
|
|
22
|
+
password: str = Column(required=False, max=128)
|
|
23
|
+
last_login: datetime = Column(required=False)
|
|
24
|
+
username: str = Column(required=False)
|
|
25
|
+
is_superuser: bool = Column(required=True, default=False)
|
|
26
|
+
is_active: bool = Column(required=True, default=True)
|
|
27
|
+
is_new: bool = Column(required=True, default=True)
|
|
28
|
+
is_staff: bool = Column(required=False, default=True)
|
|
29
|
+
title: str = Column(equired=False, max=90)
|
|
30
|
+
avatar: str = Column(max=512)
|
|
31
|
+
associate_id: str = Column(required=False)
|
|
32
|
+
associate_oid: str = Column(required=False)
|
|
33
|
+
department_code: str = Column(required=False)
|
|
34
|
+
job_code: str = Column(required=False)
|
|
35
|
+
position_id: str = Column(required=False)
|
|
36
|
+
group_id: list = Column(required=False)
|
|
37
|
+
groups: list = Column(required=False)
|
|
38
|
+
program_id: list = Column(required=False)
|
|
39
|
+
programs: list = Column(required=False)
|
|
40
|
+
start_date: datetime = Column(required=False)
|
|
41
|
+
birthday: str = Column(required=False)
|
|
42
|
+
worker_type: str = Column(required=False)
|
|
43
|
+
created_at: datetime = Column(required=False)
|
|
44
|
+
|
|
45
|
+
def birth_date(self):
|
|
46
|
+
if self.birthday:
|
|
47
|
+
_, month, day = self.birthday.split('-')
|
|
48
|
+
# Get the current year
|
|
49
|
+
current_year = datetime.now().year
|
|
50
|
+
# Create a new date string with the current year
|
|
51
|
+
new_date_str = f"{current_year}-{month}-{day}"
|
|
52
|
+
# Convert the new date string to a datetime object
|
|
53
|
+
return datetime.strptime(new_date_str, "%Y-%m-%d").date()
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
def employment_duration(self):
|
|
57
|
+
if not self.start_date:
|
|
58
|
+
return None, None, None
|
|
59
|
+
# Get today's date
|
|
60
|
+
today = datetime.now().date()
|
|
61
|
+
# employment:
|
|
62
|
+
employment = self.start_date
|
|
63
|
+
|
|
64
|
+
# Calculate the difference in years, months, days
|
|
65
|
+
years = today.year - employment.year
|
|
66
|
+
months = today.month - employment.month
|
|
67
|
+
days = today.day - employment.day
|
|
68
|
+
|
|
69
|
+
# Adjust for cases where the current month is before the start month
|
|
70
|
+
if months < 0:
|
|
71
|
+
years -= 1
|
|
72
|
+
months += 12
|
|
73
|
+
|
|
74
|
+
# Adjust for cases where the current day
|
|
75
|
+
# is before the start day in the month
|
|
76
|
+
if days < 0:
|
|
77
|
+
# Subtract one month and calculate days based on the previous month
|
|
78
|
+
months -= 1
|
|
79
|
+
if months < 0:
|
|
80
|
+
years -= 1
|
|
81
|
+
months += 12
|
|
82
|
+
# Calculate the last day of the previous month
|
|
83
|
+
last_day_of_prev_month = (
|
|
84
|
+
today.replace(day=1) - timedelta(days=1)
|
|
85
|
+
).day
|
|
86
|
+
days += last_day_of_prev_month
|
|
87
|
+
|
|
88
|
+
# Adjust months and years again if necessary
|
|
89
|
+
if months < 0:
|
|
90
|
+
years -= 1
|
|
91
|
+
months += 12
|
|
92
|
+
|
|
93
|
+
return years, months, days
|
|
94
|
+
|
|
95
|
+
class Meta:
|
|
96
|
+
driver = "pg"
|
|
97
|
+
name = AUTH_USERS_VIEW
|
|
98
|
+
schema = AUTH_DB_SCHEMA
|
|
99
|
+
description = 'View Model for getting Users.'
|
|
100
|
+
strict = True
|
|
101
|
+
frozen = False
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class UserIdentity(Model):
|
|
105
|
+
|
|
106
|
+
identity_id: UUID = Column(
|
|
107
|
+
required=False,
|
|
108
|
+
primary_key=True,
|
|
109
|
+
db_default="auto",
|
|
110
|
+
repr=False
|
|
111
|
+
)
|
|
112
|
+
display_name: str = Column(required=False)
|
|
113
|
+
title: str = Column(required=False)
|
|
114
|
+
nickname: str = Column(required=False)
|
|
115
|
+
email: str = Column(required=False)
|
|
116
|
+
phone: str = Column(required=False)
|
|
117
|
+
short_bio: Text = Column(required=False)
|
|
118
|
+
avatar: str = Column(required=False)
|
|
119
|
+
user_id: User = Column(required=False, repr=False)
|
|
120
|
+
auth_provider: str = Column(required=False)
|
|
121
|
+
auth_data: Optional[dict] = Column(required=False, repr=False)
|
|
122
|
+
attributes: Optional[dict] = Column(required=False, repr=False)
|
|
123
|
+
created_at: datetime = Column(
|
|
124
|
+
required=False,
|
|
125
|
+
default=datetime.now(),
|
|
126
|
+
repr=False
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
class Meta:
|
|
130
|
+
driver = "pg"
|
|
131
|
+
name = "user_identities"
|
|
132
|
+
description = 'Manage User Identities.'
|
|
133
|
+
schema = AUTH_DB_SCHEMA
|
|
134
|
+
strict = True
|
|
135
|
+
|
|
136
|
+
class ADUser(Model):
|
|
137
|
+
"""Active Directory Users."""
|
|
138
|
+
people_id: UUID = Column(
|
|
139
|
+
required=False,
|
|
140
|
+
primary_key=True,
|
|
141
|
+
db_default="auto",
|
|
142
|
+
repr=False
|
|
143
|
+
)
|
|
144
|
+
username: str = Column(required=False)
|
|
145
|
+
display_name: str = Column(required=False)
|
|
146
|
+
given_name: str = Column(required=False)
|
|
147
|
+
last_name: str = Column(required=False)
|
|
148
|
+
phones: Optional[list] = Column(required=False)
|
|
149
|
+
mobile: str = Column(required=False)
|
|
150
|
+
job_title: str = Column(required=False)
|
|
151
|
+
email: str = Column(required=False)
|
|
152
|
+
office_location: str = Column(required=False)
|
|
153
|
+
preferred_language: str = Column(required=False)
|
|
154
|
+
associate_id: str = Column(required=False)
|
|
155
|
+
associate_oid: str = Column(required=False)
|
|
156
|
+
job_code_title: str = Column(required=False)
|
|
157
|
+
position_id: str = Column(required=False)
|
|
158
|
+
zammad_created: bool = Column(required=False, default=False)
|
|
159
|
+
created_at: datetime = Column(
|
|
160
|
+
required=False,
|
|
161
|
+
default=datetime.now(),
|
|
162
|
+
repr=False
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
class Meta:
|
|
166
|
+
name = 'people'
|
|
167
|
+
schema = 'troc'
|
|
168
|
+
strict = True
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class ADPeople(Model):
|
|
172
|
+
"""Active Directory Users."""
|
|
173
|
+
people_id: UUID = Column(
|
|
174
|
+
required=False,
|
|
175
|
+
primary_key=True,
|
|
176
|
+
db_default="auto",
|
|
177
|
+
repr=False
|
|
178
|
+
)
|
|
179
|
+
user_id: int = Column(required=True)
|
|
180
|
+
userid: UUID = Column(required=False)
|
|
181
|
+
username: str = Column(required=False)
|
|
182
|
+
display_name: str = Column(required=False)
|
|
183
|
+
given_name: str = Column(required=False)
|
|
184
|
+
last_name: str = Column(required=False)
|
|
185
|
+
phones: Optional[list] = Column(required=False)
|
|
186
|
+
mobile: str = Column(required=False)
|
|
187
|
+
job_title: str = Column(required=False)
|
|
188
|
+
email: str = Column(required=False)
|
|
189
|
+
alt_email: str = Column(required=False)
|
|
190
|
+
office_location: str = Column(required=False)
|
|
191
|
+
preferred_language: str = Column(required=False)
|
|
192
|
+
associate_id: str = Column(required=False)
|
|
193
|
+
associate_oid: str = Column(required=False)
|
|
194
|
+
job_code_title: str = Column(required=False)
|
|
195
|
+
position_id: str = Column(required=False)
|
|
196
|
+
created_at: datetime = Column(
|
|
197
|
+
required=False,
|
|
198
|
+
default=datetime.now(),
|
|
199
|
+
repr=False
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
class Meta:
|
|
203
|
+
name = 'vw_people'
|
|
204
|
+
schema = 'troc'
|
|
205
|
+
strict = True
|