ai-parrot 0.17.2__cp310-cp310-manylinux_2_17_x86_64.manylinux2014_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.
Files changed (535) hide show
  1. agentui/.prettierrc +15 -0
  2. agentui/QUICKSTART.md +272 -0
  3. agentui/README.md +59 -0
  4. agentui/env.example +16 -0
  5. agentui/jsconfig.json +14 -0
  6. agentui/package-lock.json +4242 -0
  7. agentui/package.json +34 -0
  8. agentui/scripts/postinstall/apply-patches.mjs +260 -0
  9. agentui/src/app.css +61 -0
  10. agentui/src/app.d.ts +13 -0
  11. agentui/src/app.html +12 -0
  12. agentui/src/components/LoadingSpinner.svelte +64 -0
  13. agentui/src/components/ThemeSwitcher.svelte +159 -0
  14. agentui/src/components/index.js +4 -0
  15. agentui/src/lib/api/bots.ts +60 -0
  16. agentui/src/lib/api/chat.ts +22 -0
  17. agentui/src/lib/api/http.ts +25 -0
  18. agentui/src/lib/components/BotCard.svelte +33 -0
  19. agentui/src/lib/components/ChatBubble.svelte +63 -0
  20. agentui/src/lib/components/Toast.svelte +21 -0
  21. agentui/src/lib/config.ts +20 -0
  22. agentui/src/lib/stores/auth.svelte.ts +73 -0
  23. agentui/src/lib/stores/theme.svelte.js +64 -0
  24. agentui/src/lib/stores/toast.svelte.ts +31 -0
  25. agentui/src/lib/utils/conversation.ts +39 -0
  26. agentui/src/routes/+layout.svelte +20 -0
  27. agentui/src/routes/+page.svelte +232 -0
  28. agentui/src/routes/login/+page.svelte +200 -0
  29. agentui/src/routes/talk/[agentId]/+page.svelte +297 -0
  30. agentui/src/routes/talk/[agentId]/+page.ts +7 -0
  31. agentui/static/README.md +1 -0
  32. agentui/svelte.config.js +11 -0
  33. agentui/tailwind.config.ts +53 -0
  34. agentui/tsconfig.json +3 -0
  35. agentui/vite.config.ts +10 -0
  36. ai_parrot-0.17.2.dist-info/METADATA +472 -0
  37. ai_parrot-0.17.2.dist-info/RECORD +535 -0
  38. ai_parrot-0.17.2.dist-info/WHEEL +6 -0
  39. ai_parrot-0.17.2.dist-info/entry_points.txt +2 -0
  40. ai_parrot-0.17.2.dist-info/licenses/LICENSE +21 -0
  41. ai_parrot-0.17.2.dist-info/top_level.txt +6 -0
  42. crew-builder/.prettierrc +15 -0
  43. crew-builder/QUICKSTART.md +259 -0
  44. crew-builder/README.md +113 -0
  45. crew-builder/env.example +17 -0
  46. crew-builder/jsconfig.json +14 -0
  47. crew-builder/package-lock.json +4182 -0
  48. crew-builder/package.json +37 -0
  49. crew-builder/scripts/postinstall/apply-patches.mjs +260 -0
  50. crew-builder/src/app.css +62 -0
  51. crew-builder/src/app.d.ts +13 -0
  52. crew-builder/src/app.html +12 -0
  53. crew-builder/src/components/LoadingSpinner.svelte +64 -0
  54. crew-builder/src/components/ThemeSwitcher.svelte +149 -0
  55. crew-builder/src/components/index.js +9 -0
  56. crew-builder/src/lib/api/bots.ts +60 -0
  57. crew-builder/src/lib/api/chat.ts +80 -0
  58. crew-builder/src/lib/api/client.ts +56 -0
  59. crew-builder/src/lib/api/crew/crew.ts +136 -0
  60. crew-builder/src/lib/api/index.ts +5 -0
  61. crew-builder/src/lib/api/o365/auth.ts +65 -0
  62. crew-builder/src/lib/auth/auth.ts +54 -0
  63. crew-builder/src/lib/components/AgentNode.svelte +43 -0
  64. crew-builder/src/lib/components/BotCard.svelte +33 -0
  65. crew-builder/src/lib/components/ChatBubble.svelte +67 -0
  66. crew-builder/src/lib/components/ConfigPanel.svelte +278 -0
  67. crew-builder/src/lib/components/JsonTreeNode.svelte +76 -0
  68. crew-builder/src/lib/components/JsonViewer.svelte +24 -0
  69. crew-builder/src/lib/components/MarkdownEditor.svelte +48 -0
  70. crew-builder/src/lib/components/ThemeToggle.svelte +36 -0
  71. crew-builder/src/lib/components/Toast.svelte +67 -0
  72. crew-builder/src/lib/components/Toolbar.svelte +157 -0
  73. crew-builder/src/lib/components/index.ts +10 -0
  74. crew-builder/src/lib/config.ts +8 -0
  75. crew-builder/src/lib/stores/auth.svelte.ts +228 -0
  76. crew-builder/src/lib/stores/crewStore.ts +369 -0
  77. crew-builder/src/lib/stores/theme.svelte.js +145 -0
  78. crew-builder/src/lib/stores/toast.svelte.ts +69 -0
  79. crew-builder/src/lib/utils/conversation.ts +39 -0
  80. crew-builder/src/lib/utils/markdown.ts +122 -0
  81. crew-builder/src/lib/utils/talkHistory.ts +47 -0
  82. crew-builder/src/routes/+layout.svelte +20 -0
  83. crew-builder/src/routes/+page.svelte +539 -0
  84. crew-builder/src/routes/agents/+page.svelte +247 -0
  85. crew-builder/src/routes/agents/[agentId]/+page.svelte +288 -0
  86. crew-builder/src/routes/agents/[agentId]/+page.ts +7 -0
  87. crew-builder/src/routes/builder/+page.svelte +204 -0
  88. crew-builder/src/routes/crew/ask/+page.svelte +1052 -0
  89. crew-builder/src/routes/crew/ask/+page.ts +1 -0
  90. crew-builder/src/routes/integrations/o365/+page.svelte +304 -0
  91. crew-builder/src/routes/login/+page.svelte +197 -0
  92. crew-builder/src/routes/talk/[agentId]/+page.svelte +487 -0
  93. crew-builder/src/routes/talk/[agentId]/+page.ts +7 -0
  94. crew-builder/static/README.md +1 -0
  95. crew-builder/svelte.config.js +11 -0
  96. crew-builder/tailwind.config.ts +53 -0
  97. crew-builder/tsconfig.json +3 -0
  98. crew-builder/vite.config.ts +10 -0
  99. mcp_servers/calculator_server.py +309 -0
  100. parrot/__init__.py +27 -0
  101. parrot/__pycache__/__init__.cpython-310.pyc +0 -0
  102. parrot/__pycache__/version.cpython-310.pyc +0 -0
  103. parrot/_version.py +34 -0
  104. parrot/a2a/__init__.py +48 -0
  105. parrot/a2a/client.py +658 -0
  106. parrot/a2a/discovery.py +89 -0
  107. parrot/a2a/mixin.py +257 -0
  108. parrot/a2a/models.py +376 -0
  109. parrot/a2a/server.py +770 -0
  110. parrot/agents/__init__.py +29 -0
  111. parrot/bots/__init__.py +12 -0
  112. parrot/bots/a2a_agent.py +19 -0
  113. parrot/bots/abstract.py +3139 -0
  114. parrot/bots/agent.py +1129 -0
  115. parrot/bots/basic.py +9 -0
  116. parrot/bots/chatbot.py +669 -0
  117. parrot/bots/data.py +1618 -0
  118. parrot/bots/database/__init__.py +5 -0
  119. parrot/bots/database/abstract.py +3071 -0
  120. parrot/bots/database/cache.py +286 -0
  121. parrot/bots/database/models.py +468 -0
  122. parrot/bots/database/prompts.py +154 -0
  123. parrot/bots/database/retries.py +98 -0
  124. parrot/bots/database/router.py +269 -0
  125. parrot/bots/database/sql.py +41 -0
  126. parrot/bots/db/__init__.py +6 -0
  127. parrot/bots/db/abstract.py +556 -0
  128. parrot/bots/db/bigquery.py +602 -0
  129. parrot/bots/db/cache.py +85 -0
  130. parrot/bots/db/documentdb.py +668 -0
  131. parrot/bots/db/elastic.py +1014 -0
  132. parrot/bots/db/influx.py +898 -0
  133. parrot/bots/db/mock.py +96 -0
  134. parrot/bots/db/multi.py +783 -0
  135. parrot/bots/db/prompts.py +185 -0
  136. parrot/bots/db/sql.py +1255 -0
  137. parrot/bots/db/tools.py +212 -0
  138. parrot/bots/document.py +680 -0
  139. parrot/bots/hrbot.py +15 -0
  140. parrot/bots/kb.py +170 -0
  141. parrot/bots/mcp.py +36 -0
  142. parrot/bots/orchestration/README.md +463 -0
  143. parrot/bots/orchestration/__init__.py +1 -0
  144. parrot/bots/orchestration/agent.py +155 -0
  145. parrot/bots/orchestration/crew.py +3330 -0
  146. parrot/bots/orchestration/fsm.py +1179 -0
  147. parrot/bots/orchestration/hr.py +434 -0
  148. parrot/bots/orchestration/storage/__init__.py +4 -0
  149. parrot/bots/orchestration/storage/memory.py +100 -0
  150. parrot/bots/orchestration/storage/mixin.py +119 -0
  151. parrot/bots/orchestration/verify.py +202 -0
  152. parrot/bots/product.py +204 -0
  153. parrot/bots/prompts/__init__.py +96 -0
  154. parrot/bots/prompts/agents.py +155 -0
  155. parrot/bots/prompts/data.py +216 -0
  156. parrot/bots/prompts/output_generation.py +8 -0
  157. parrot/bots/scraper/__init__.py +3 -0
  158. parrot/bots/scraper/models.py +122 -0
  159. parrot/bots/scraper/scraper.py +1173 -0
  160. parrot/bots/scraper/templates.py +115 -0
  161. parrot/bots/stores/__init__.py +5 -0
  162. parrot/bots/stores/local.py +172 -0
  163. parrot/bots/webdev.py +81 -0
  164. parrot/cli.py +17 -0
  165. parrot/clients/__init__.py +16 -0
  166. parrot/clients/base.py +1491 -0
  167. parrot/clients/claude.py +1191 -0
  168. parrot/clients/factory.py +129 -0
  169. parrot/clients/google.py +4567 -0
  170. parrot/clients/gpt.py +1975 -0
  171. parrot/clients/grok.py +432 -0
  172. parrot/clients/groq.py +986 -0
  173. parrot/clients/hf.py +582 -0
  174. parrot/clients/models.py +18 -0
  175. parrot/conf.py +395 -0
  176. parrot/embeddings/__init__.py +9 -0
  177. parrot/embeddings/base.py +157 -0
  178. parrot/embeddings/google.py +98 -0
  179. parrot/embeddings/huggingface.py +74 -0
  180. parrot/embeddings/openai.py +84 -0
  181. parrot/embeddings/processor.py +88 -0
  182. parrot/exceptions.c +13868 -0
  183. parrot/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
  184. parrot/exceptions.pxd +22 -0
  185. parrot/exceptions.pxi +15 -0
  186. parrot/exceptions.pyx +44 -0
  187. parrot/generators/__init__.py +29 -0
  188. parrot/generators/base.py +200 -0
  189. parrot/generators/html.py +293 -0
  190. parrot/generators/react.py +205 -0
  191. parrot/generators/streamlit.py +203 -0
  192. parrot/generators/template.py +105 -0
  193. parrot/handlers/__init__.py +4 -0
  194. parrot/handlers/agent.py +861 -0
  195. parrot/handlers/agents/__init__.py +1 -0
  196. parrot/handlers/agents/abstract.py +900 -0
  197. parrot/handlers/bots.py +338 -0
  198. parrot/handlers/chat.py +915 -0
  199. parrot/handlers/creation.sql +192 -0
  200. parrot/handlers/crew/ARCHITECTURE.md +362 -0
  201. parrot/handlers/crew/README_BOTMANAGER_PERSISTENCE.md +303 -0
  202. parrot/handlers/crew/README_REDIS_PERSISTENCE.md +366 -0
  203. parrot/handlers/crew/__init__.py +0 -0
  204. parrot/handlers/crew/handler.py +801 -0
  205. parrot/handlers/crew/models.py +229 -0
  206. parrot/handlers/crew/redis_persistence.py +523 -0
  207. parrot/handlers/jobs/__init__.py +10 -0
  208. parrot/handlers/jobs/job.py +384 -0
  209. parrot/handlers/jobs/mixin.py +627 -0
  210. parrot/handlers/jobs/models.py +115 -0
  211. parrot/handlers/jobs/worker.py +31 -0
  212. parrot/handlers/models.py +596 -0
  213. parrot/handlers/o365_auth.py +105 -0
  214. parrot/handlers/stream.py +337 -0
  215. parrot/interfaces/__init__.py +6 -0
  216. parrot/interfaces/aws.py +143 -0
  217. parrot/interfaces/credentials.py +113 -0
  218. parrot/interfaces/database.py +27 -0
  219. parrot/interfaces/google.py +1123 -0
  220. parrot/interfaces/hierarchy.py +1227 -0
  221. parrot/interfaces/http.py +651 -0
  222. parrot/interfaces/images/__init__.py +0 -0
  223. parrot/interfaces/images/plugins/__init__.py +24 -0
  224. parrot/interfaces/images/plugins/abstract.py +58 -0
  225. parrot/interfaces/images/plugins/analisys.py +148 -0
  226. parrot/interfaces/images/plugins/classify.py +150 -0
  227. parrot/interfaces/images/plugins/classifybase.py +182 -0
  228. parrot/interfaces/images/plugins/detect.py +150 -0
  229. parrot/interfaces/images/plugins/exif.py +1103 -0
  230. parrot/interfaces/images/plugins/hash.py +52 -0
  231. parrot/interfaces/images/plugins/vision.py +104 -0
  232. parrot/interfaces/images/plugins/yolo.py +66 -0
  233. parrot/interfaces/images/plugins/zerodetect.py +197 -0
  234. parrot/interfaces/o365.py +978 -0
  235. parrot/interfaces/onedrive.py +822 -0
  236. parrot/interfaces/sharepoint.py +1435 -0
  237. parrot/interfaces/soap.py +257 -0
  238. parrot/loaders/__init__.py +8 -0
  239. parrot/loaders/abstract.py +1131 -0
  240. parrot/loaders/audio.py +199 -0
  241. parrot/loaders/basepdf.py +53 -0
  242. parrot/loaders/basevideo.py +1568 -0
  243. parrot/loaders/csv.py +409 -0
  244. parrot/loaders/docx.py +116 -0
  245. parrot/loaders/epubloader.py +316 -0
  246. parrot/loaders/excel.py +199 -0
  247. parrot/loaders/factory.py +55 -0
  248. parrot/loaders/files/__init__.py +0 -0
  249. parrot/loaders/files/abstract.py +39 -0
  250. parrot/loaders/files/html.py +26 -0
  251. parrot/loaders/files/text.py +63 -0
  252. parrot/loaders/html.py +152 -0
  253. parrot/loaders/markdown.py +442 -0
  254. parrot/loaders/pdf.py +373 -0
  255. parrot/loaders/pdfmark.py +320 -0
  256. parrot/loaders/pdftables.py +506 -0
  257. parrot/loaders/ppt.py +476 -0
  258. parrot/loaders/qa.py +63 -0
  259. parrot/loaders/splitters/__init__.py +10 -0
  260. parrot/loaders/splitters/base.py +138 -0
  261. parrot/loaders/splitters/md.py +228 -0
  262. parrot/loaders/splitters/token.py +143 -0
  263. parrot/loaders/txt.py +26 -0
  264. parrot/loaders/video.py +89 -0
  265. parrot/loaders/videolocal.py +218 -0
  266. parrot/loaders/videounderstanding.py +377 -0
  267. parrot/loaders/vimeo.py +167 -0
  268. parrot/loaders/web.py +599 -0
  269. parrot/loaders/youtube.py +504 -0
  270. parrot/manager/__init__.py +5 -0
  271. parrot/manager/manager.py +1030 -0
  272. parrot/mcp/__init__.py +28 -0
  273. parrot/mcp/adapter.py +105 -0
  274. parrot/mcp/cli.py +174 -0
  275. parrot/mcp/client.py +119 -0
  276. parrot/mcp/config.py +75 -0
  277. parrot/mcp/integration.py +842 -0
  278. parrot/mcp/oauth.py +933 -0
  279. parrot/mcp/server.py +225 -0
  280. parrot/mcp/transports/__init__.py +3 -0
  281. parrot/mcp/transports/base.py +279 -0
  282. parrot/mcp/transports/grpc_session.py +163 -0
  283. parrot/mcp/transports/http.py +312 -0
  284. parrot/mcp/transports/mcp.proto +108 -0
  285. parrot/mcp/transports/quic.py +1082 -0
  286. parrot/mcp/transports/sse.py +330 -0
  287. parrot/mcp/transports/stdio.py +309 -0
  288. parrot/mcp/transports/unix.py +395 -0
  289. parrot/mcp/transports/websocket.py +547 -0
  290. parrot/memory/__init__.py +16 -0
  291. parrot/memory/abstract.py +209 -0
  292. parrot/memory/agent.py +32 -0
  293. parrot/memory/cache.py +175 -0
  294. parrot/memory/core.py +555 -0
  295. parrot/memory/file.py +153 -0
  296. parrot/memory/mem.py +131 -0
  297. parrot/memory/redis.py +613 -0
  298. parrot/models/__init__.py +46 -0
  299. parrot/models/basic.py +118 -0
  300. parrot/models/compliance.py +208 -0
  301. parrot/models/crew.py +395 -0
  302. parrot/models/detections.py +654 -0
  303. parrot/models/generation.py +85 -0
  304. parrot/models/google.py +223 -0
  305. parrot/models/groq.py +23 -0
  306. parrot/models/openai.py +30 -0
  307. parrot/models/outputs.py +285 -0
  308. parrot/models/responses.py +938 -0
  309. parrot/notifications/__init__.py +743 -0
  310. parrot/openapi/__init__.py +3 -0
  311. parrot/openapi/components.yaml +641 -0
  312. parrot/openapi/config.py +322 -0
  313. parrot/outputs/__init__.py +32 -0
  314. parrot/outputs/formats/__init__.py +108 -0
  315. parrot/outputs/formats/altair.py +359 -0
  316. parrot/outputs/formats/application.py +122 -0
  317. parrot/outputs/formats/base.py +351 -0
  318. parrot/outputs/formats/bokeh.py +356 -0
  319. parrot/outputs/formats/card.py +424 -0
  320. parrot/outputs/formats/chart.py +436 -0
  321. parrot/outputs/formats/d3.py +255 -0
  322. parrot/outputs/formats/echarts.py +310 -0
  323. parrot/outputs/formats/generators/__init__.py +0 -0
  324. parrot/outputs/formats/generators/abstract.py +61 -0
  325. parrot/outputs/formats/generators/panel.py +145 -0
  326. parrot/outputs/formats/generators/streamlit.py +86 -0
  327. parrot/outputs/formats/generators/terminal.py +63 -0
  328. parrot/outputs/formats/holoviews.py +310 -0
  329. parrot/outputs/formats/html.py +147 -0
  330. parrot/outputs/formats/jinja2.py +46 -0
  331. parrot/outputs/formats/json.py +87 -0
  332. parrot/outputs/formats/map.py +933 -0
  333. parrot/outputs/formats/markdown.py +172 -0
  334. parrot/outputs/formats/matplotlib.py +237 -0
  335. parrot/outputs/formats/mixins/__init__.py +0 -0
  336. parrot/outputs/formats/mixins/emaps.py +855 -0
  337. parrot/outputs/formats/plotly.py +341 -0
  338. parrot/outputs/formats/seaborn.py +310 -0
  339. parrot/outputs/formats/table.py +397 -0
  340. parrot/outputs/formats/template_report.py +138 -0
  341. parrot/outputs/formats/yaml.py +125 -0
  342. parrot/outputs/formatter.py +152 -0
  343. parrot/outputs/templates/__init__.py +95 -0
  344. parrot/pipelines/__init__.py +0 -0
  345. parrot/pipelines/abstract.py +210 -0
  346. parrot/pipelines/detector.py +124 -0
  347. parrot/pipelines/models.py +90 -0
  348. parrot/pipelines/planogram.py +3002 -0
  349. parrot/pipelines/table.sql +97 -0
  350. parrot/plugins/__init__.py +106 -0
  351. parrot/plugins/importer.py +80 -0
  352. parrot/py.typed +0 -0
  353. parrot/registry/__init__.py +18 -0
  354. parrot/registry/registry.py +594 -0
  355. parrot/scheduler/__init__.py +1189 -0
  356. parrot/scheduler/models.py +60 -0
  357. parrot/security/__init__.py +16 -0
  358. parrot/security/prompt_injection.py +268 -0
  359. parrot/security/security_events.sql +25 -0
  360. parrot/services/__init__.py +1 -0
  361. parrot/services/mcp/__init__.py +8 -0
  362. parrot/services/mcp/config.py +13 -0
  363. parrot/services/mcp/server.py +295 -0
  364. parrot/services/o365_remote_auth.py +235 -0
  365. parrot/stores/__init__.py +7 -0
  366. parrot/stores/abstract.py +352 -0
  367. parrot/stores/arango.py +1090 -0
  368. parrot/stores/bigquery.py +1377 -0
  369. parrot/stores/cache.py +106 -0
  370. parrot/stores/empty.py +10 -0
  371. parrot/stores/faiss_store.py +1157 -0
  372. parrot/stores/kb/__init__.py +9 -0
  373. parrot/stores/kb/abstract.py +68 -0
  374. parrot/stores/kb/cache.py +165 -0
  375. parrot/stores/kb/doc.py +325 -0
  376. parrot/stores/kb/hierarchy.py +346 -0
  377. parrot/stores/kb/local.py +457 -0
  378. parrot/stores/kb/prompt.py +28 -0
  379. parrot/stores/kb/redis.py +659 -0
  380. parrot/stores/kb/store.py +115 -0
  381. parrot/stores/kb/user.py +374 -0
  382. parrot/stores/models.py +59 -0
  383. parrot/stores/pgvector.py +3 -0
  384. parrot/stores/postgres.py +2853 -0
  385. parrot/stores/utils/__init__.py +0 -0
  386. parrot/stores/utils/chunking.py +197 -0
  387. parrot/telemetry/__init__.py +3 -0
  388. parrot/telemetry/mixin.py +111 -0
  389. parrot/template/__init__.py +3 -0
  390. parrot/template/engine.py +259 -0
  391. parrot/tools/__init__.py +23 -0
  392. parrot/tools/abstract.py +644 -0
  393. parrot/tools/agent.py +363 -0
  394. parrot/tools/arangodbsearch.py +537 -0
  395. parrot/tools/arxiv_tool.py +188 -0
  396. parrot/tools/calculator/__init__.py +3 -0
  397. parrot/tools/calculator/operations/__init__.py +38 -0
  398. parrot/tools/calculator/operations/calculus.py +80 -0
  399. parrot/tools/calculator/operations/statistics.py +76 -0
  400. parrot/tools/calculator/tool.py +150 -0
  401. parrot/tools/cloudwatch.py +988 -0
  402. parrot/tools/codeinterpreter/__init__.py +127 -0
  403. parrot/tools/codeinterpreter/executor.py +371 -0
  404. parrot/tools/codeinterpreter/internals.py +473 -0
  405. parrot/tools/codeinterpreter/models.py +643 -0
  406. parrot/tools/codeinterpreter/prompts.py +224 -0
  407. parrot/tools/codeinterpreter/tool.py +664 -0
  408. parrot/tools/company_info/__init__.py +6 -0
  409. parrot/tools/company_info/tool.py +1138 -0
  410. parrot/tools/correlationanalysis.py +437 -0
  411. parrot/tools/database/abstract.py +286 -0
  412. parrot/tools/database/bq.py +115 -0
  413. parrot/tools/database/cache.py +284 -0
  414. parrot/tools/database/models.py +95 -0
  415. parrot/tools/database/pg.py +343 -0
  416. parrot/tools/databasequery.py +1159 -0
  417. parrot/tools/db.py +1800 -0
  418. parrot/tools/ddgo.py +370 -0
  419. parrot/tools/decorators.py +271 -0
  420. parrot/tools/dftohtml.py +282 -0
  421. parrot/tools/document.py +549 -0
  422. parrot/tools/ecs.py +819 -0
  423. parrot/tools/edareport.py +368 -0
  424. parrot/tools/elasticsearch.py +1049 -0
  425. parrot/tools/employees.py +462 -0
  426. parrot/tools/epson/__init__.py +96 -0
  427. parrot/tools/excel.py +683 -0
  428. parrot/tools/file/__init__.py +13 -0
  429. parrot/tools/file/abstract.py +76 -0
  430. parrot/tools/file/gcs.py +378 -0
  431. parrot/tools/file/local.py +284 -0
  432. parrot/tools/file/s3.py +511 -0
  433. parrot/tools/file/tmp.py +309 -0
  434. parrot/tools/file/tool.py +501 -0
  435. parrot/tools/file_reader.py +129 -0
  436. parrot/tools/flowtask/__init__.py +19 -0
  437. parrot/tools/flowtask/tool.py +761 -0
  438. parrot/tools/gittoolkit.py +508 -0
  439. parrot/tools/google/__init__.py +18 -0
  440. parrot/tools/google/base.py +169 -0
  441. parrot/tools/google/tools.py +1251 -0
  442. parrot/tools/googlelocation.py +5 -0
  443. parrot/tools/googleroutes.py +5 -0
  444. parrot/tools/googlesearch.py +5 -0
  445. parrot/tools/googlesitesearch.py +5 -0
  446. parrot/tools/googlevoice.py +2 -0
  447. parrot/tools/gvoice.py +695 -0
  448. parrot/tools/ibisworld/README.md +225 -0
  449. parrot/tools/ibisworld/__init__.py +11 -0
  450. parrot/tools/ibisworld/tool.py +366 -0
  451. parrot/tools/jiratoolkit.py +1718 -0
  452. parrot/tools/manager.py +1098 -0
  453. parrot/tools/math.py +152 -0
  454. parrot/tools/metadata.py +476 -0
  455. parrot/tools/msteams.py +1621 -0
  456. parrot/tools/msword.py +635 -0
  457. parrot/tools/multidb.py +580 -0
  458. parrot/tools/multistoresearch.py +369 -0
  459. parrot/tools/networkninja.py +167 -0
  460. parrot/tools/nextstop/__init__.py +4 -0
  461. parrot/tools/nextstop/base.py +286 -0
  462. parrot/tools/nextstop/employee.py +733 -0
  463. parrot/tools/nextstop/store.py +462 -0
  464. parrot/tools/notification.py +435 -0
  465. parrot/tools/o365/__init__.py +42 -0
  466. parrot/tools/o365/base.py +295 -0
  467. parrot/tools/o365/bundle.py +522 -0
  468. parrot/tools/o365/events.py +554 -0
  469. parrot/tools/o365/mail.py +992 -0
  470. parrot/tools/o365/onedrive.py +497 -0
  471. parrot/tools/o365/sharepoint.py +641 -0
  472. parrot/tools/openapi_toolkit.py +904 -0
  473. parrot/tools/openweather.py +527 -0
  474. parrot/tools/pdfprint.py +1001 -0
  475. parrot/tools/powerbi.py +518 -0
  476. parrot/tools/powerpoint.py +1113 -0
  477. parrot/tools/pricestool.py +146 -0
  478. parrot/tools/products/__init__.py +246 -0
  479. parrot/tools/prophet_tool.py +171 -0
  480. parrot/tools/pythonpandas.py +630 -0
  481. parrot/tools/pythonrepl.py +910 -0
  482. parrot/tools/qsource.py +436 -0
  483. parrot/tools/querytoolkit.py +395 -0
  484. parrot/tools/quickeda.py +827 -0
  485. parrot/tools/resttool.py +553 -0
  486. parrot/tools/retail/__init__.py +0 -0
  487. parrot/tools/retail/bby.py +528 -0
  488. parrot/tools/sandboxtool.py +703 -0
  489. parrot/tools/sassie/__init__.py +352 -0
  490. parrot/tools/scraping/__init__.py +7 -0
  491. parrot/tools/scraping/docs/select.md +466 -0
  492. parrot/tools/scraping/documentation.md +1278 -0
  493. parrot/tools/scraping/driver.py +436 -0
  494. parrot/tools/scraping/models.py +576 -0
  495. parrot/tools/scraping/options.py +85 -0
  496. parrot/tools/scraping/orchestrator.py +517 -0
  497. parrot/tools/scraping/readme.md +740 -0
  498. parrot/tools/scraping/tool.py +3115 -0
  499. parrot/tools/seasonaldetection.py +642 -0
  500. parrot/tools/shell_tool/__init__.py +5 -0
  501. parrot/tools/shell_tool/actions.py +408 -0
  502. parrot/tools/shell_tool/engine.py +155 -0
  503. parrot/tools/shell_tool/models.py +322 -0
  504. parrot/tools/shell_tool/tool.py +442 -0
  505. parrot/tools/site_search.py +214 -0
  506. parrot/tools/textfile.py +418 -0
  507. parrot/tools/think.py +378 -0
  508. parrot/tools/toolkit.py +298 -0
  509. parrot/tools/webapp_tool.py +187 -0
  510. parrot/tools/whatif.py +1279 -0
  511. parrot/tools/workday/MULTI_WSDL_EXAMPLE.md +249 -0
  512. parrot/tools/workday/__init__.py +6 -0
  513. parrot/tools/workday/models.py +1389 -0
  514. parrot/tools/workday/tool.py +1293 -0
  515. parrot/tools/yfinance_tool.py +306 -0
  516. parrot/tools/zipcode.py +217 -0
  517. parrot/utils/__init__.py +2 -0
  518. parrot/utils/helpers.py +73 -0
  519. parrot/utils/parsers/__init__.py +5 -0
  520. parrot/utils/parsers/toml.c +12078 -0
  521. parrot/utils/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
  522. parrot/utils/parsers/toml.pyx +21 -0
  523. parrot/utils/toml.py +11 -0
  524. parrot/utils/types.cpp +20936 -0
  525. parrot/utils/types.cpython-310-x86_64-linux-gnu.so +0 -0
  526. parrot/utils/types.pyx +213 -0
  527. parrot/utils/uv.py +11 -0
  528. parrot/version.py +10 -0
  529. parrot/yaml-rs/Cargo.lock +350 -0
  530. parrot/yaml-rs/Cargo.toml +19 -0
  531. parrot/yaml-rs/pyproject.toml +19 -0
  532. parrot/yaml-rs/python/yaml_rs/__init__.py +81 -0
  533. parrot/yaml-rs/src/lib.rs +222 -0
  534. requirements/docker-compose.yml +24 -0
  535. requirements/requirements-dev.txt +21 -0
@@ -0,0 +1,306 @@
1
+ """YFinance tool for retrieving market data via Yahoo Finance."""
2
+ from __future__ import annotations
3
+ import asyncio
4
+ from datetime import datetime, timezone
5
+ from typing import Any, Dict, Optional, Literal, Union
6
+ import numpy as np
7
+ import pandas as pd
8
+ import yfinance as yf
9
+ from pydantic import Field, field_validator
10
+
11
+ from .abstract import AbstractTool, AbstractToolArgsSchema, ToolResult
12
+
13
+
14
+ class YFinanceArgs(AbstractToolArgsSchema):
15
+ """Argument schema for :class:`YFinanceTool`."""
16
+
17
+ ticker: str = Field(
18
+ ...,
19
+ description="Ticker symbol to query (for example: AAPL, MSFT, TSLA).",
20
+ min_length=1,
21
+ max_length=32,
22
+ )
23
+ action: Literal["quote", "info", "history", "financials"] = Field(
24
+ "quote",
25
+ description=(
26
+ "Type of data to retrieve. "
27
+ "'quote' returns the latest market quote, 'info' returns company details, "
28
+ "'history' returns historical price data, and 'financials' returns financial statements."
29
+ ),
30
+ )
31
+ period: Optional[str] = Field(
32
+ "1mo",
33
+ description=(
34
+ "Period for historical data (used when action='history'). Examples: '1d', '5d', '1mo', "
35
+ "'3mo', '6mo', '1y', '5y', '10y', 'ytd', 'max'."
36
+ ),
37
+ )
38
+ interval: Optional[str] = Field(
39
+ "1d",
40
+ description=(
41
+ "Data interval for historical data (used when action='history'). Examples: '1m', '5m', '15m', "
42
+ "'1h', '1d', '1wk', '1mo'."
43
+ ),
44
+ )
45
+ start: Optional[Union[datetime, str]] = Field(
46
+ None,
47
+ description=(
48
+ "Optional start date for historical data. Accepts ISO formatted strings or datetime objects."
49
+ ),
50
+ )
51
+ end: Optional[Union[datetime, str]] = Field(
52
+ None,
53
+ description=(
54
+ "Optional end date for historical data. Accepts ISO formatted strings or datetime objects."
55
+ ),
56
+ )
57
+ auto_adjust: bool = Field(
58
+ True,
59
+ description="Adjust historical data for dividends and splits (used when action='history').",
60
+ )
61
+ include_actions: bool = Field(
62
+ False,
63
+ description="Include dividends and splits columns in historical results (action='history').",
64
+ )
65
+
66
+ @field_validator("ticker")
67
+ @classmethod
68
+ def normalize_ticker(cls, value: str) -> str:
69
+ if (ticker := value.strip().upper()):
70
+ return ticker
71
+ raise ValueError("Ticker symbol cannot be empty")
72
+
73
+
74
+
75
+ class YFinanceTool(AbstractTool):
76
+ """Retrieve quotes, company information, and financial statements via Yahoo Finance."""
77
+
78
+ name = "yfinance_tool"
79
+ description = (
80
+ "Access Yahoo Finance market data including latest quotes, company information, "
81
+ "historical prices, and financial statements for a given ticker symbol."
82
+ )
83
+ args_schema = YFinanceArgs
84
+
85
+ async def _execute(self, **kwargs: Any) -> ToolResult:
86
+ args = self.args_schema(**kwargs)
87
+ loop = asyncio.get_running_loop()
88
+ return await loop.run_in_executor(None, self._run, args)
89
+
90
+ def _run(self, args: YFinanceArgs) -> ToolResult:
91
+ ticker = yf.Ticker(args.ticker)
92
+ action = args.action
93
+
94
+ retrieved_at = datetime.now(tz=timezone.utc).isoformat() + "Z"
95
+
96
+ if action == "quote":
97
+ payload = self._get_quote(ticker, args, retrieved_at)
98
+ elif action == "info":
99
+ payload = self._get_info(ticker, args, retrieved_at)
100
+ elif action == "history":
101
+ payload = self._get_history(ticker, args, retrieved_at)
102
+ elif action == "financials":
103
+ payload = self._get_financials(ticker, args, retrieved_at)
104
+ else:
105
+ raise ValueError(f"Unsupported action: {action}")
106
+
107
+ return ToolResult(
108
+ status="success",
109
+ result=payload,
110
+ metadata={
111
+ "symbol": args.ticker,
112
+ "action": action,
113
+ "source": "yfinance",
114
+ "retrieved_at": retrieved_at,
115
+ },
116
+ )
117
+
118
+ def _get_quote(
119
+ self, ticker: yf.Ticker, args: YFinanceArgs, retrieved_at: str
120
+ ) -> Dict[str, Any]:
121
+ fast_info: Dict[str, Any] = {}
122
+ info: Dict[str, Any] = {}
123
+
124
+ try:
125
+ fast_info = dict(getattr(ticker, "fast_info", {}) or {})
126
+ except Exception as exc: # pragma: no cover - defensive
127
+ self.logger.warning("Unable to retrieve fast_info for %s: %s", args.ticker, exc)
128
+
129
+ try:
130
+ info = ticker.get_info() or {}
131
+ except Exception as exc: # pragma: no cover - defensive
132
+ self.logger.warning("Unable to retrieve info for %s: %s", args.ticker, exc)
133
+
134
+ def _extract_price() -> Optional[float]:
135
+ candidates = [
136
+ fast_info.get("lastPrice"),
137
+ fast_info.get("last_price"),
138
+ fast_info.get("regularMarketPrice"),
139
+ info.get("regularMarketPrice"),
140
+ ]
141
+ for candidate in candidates:
142
+ if candidate is not None:
143
+ return self._to_native_number(candidate)
144
+ return None
145
+
146
+ summary = {
147
+ "last_price": _extract_price(),
148
+ "currency": fast_info.get("currency") or info.get("currency"),
149
+ "previous_close": self._to_native_number(
150
+ fast_info.get("previousClose") or fast_info.get("previous_close") or info.get("previousClose")
151
+ ),
152
+ "open": self._to_native_number(fast_info.get("open") or info.get("open")),
153
+ "day_range": {
154
+ "low": self._to_native_number(
155
+ fast_info.get("dayLow") or fast_info.get("day_low") or info.get("dayLow")
156
+ ),
157
+ "high": self._to_native_number(
158
+ fast_info.get("dayHigh") or fast_info.get("day_high") or info.get("dayHigh")
159
+ ),
160
+ },
161
+ "volume": self._to_native_number(fast_info.get("volume") or info.get("volume")),
162
+ "market_cap": self._to_native_number(
163
+ fast_info.get("marketCap") or fast_info.get("market_cap") or info.get("marketCap")
164
+ ),
165
+ "exchange": info.get("exchange") or info.get("fullExchangeName"),
166
+ "timestamp": datetime.utcnow().isoformat() + "Z",
167
+ }
168
+
169
+ return {
170
+ "ticker": args.ticker,
171
+ "retrieved_at": retrieved_at,
172
+ "quote": summary,
173
+ "fast_info": self._clean_nested(fast_info),
174
+ "info_excerpt": {
175
+ k: info.get(k)
176
+ for k in ("longName", "shortName", "quoteType", "sector", "industry")
177
+ if k in info
178
+ },
179
+ }
180
+
181
+ def _get_info(
182
+ self, ticker: yf.Ticker, args: YFinanceArgs, retrieved_at: str
183
+ ) -> Dict[str, Any]:
184
+ try:
185
+ info = ticker.get_info() or {}
186
+ except Exception as exc:
187
+ raise ValueError(f"Unable to retrieve company info for {args.ticker}: {exc}") from exc
188
+
189
+ return {
190
+ "ticker": args.ticker,
191
+ "retrieved_at": retrieved_at,
192
+ "info": self._clean_nested(info),
193
+ }
194
+
195
+ def _get_history(
196
+ self, ticker: yf.Ticker, args: YFinanceArgs, retrieved_at: str
197
+ ) -> Dict[str, Any]:
198
+ history_df = ticker.history(
199
+ period=args.period,
200
+ interval=args.interval,
201
+ start=args.start,
202
+ end=args.end,
203
+ auto_adjust=args.auto_adjust,
204
+ actions=args.include_actions,
205
+ )
206
+
207
+ records = []
208
+ if not history_df.empty:
209
+ history_df = history_df.reset_index()
210
+ for row in history_df.to_dict(orient="records"):
211
+ cleaned_row = {
212
+ key: (
213
+ value.isoformat()
214
+ if isinstance(value, (pd.Timestamp, datetime))
215
+ else self._clean_value(value)
216
+ )
217
+ for key, value in row.items()
218
+ }
219
+ records.append(cleaned_row)
220
+
221
+ return {
222
+ "ticker": args.ticker,
223
+ "retrieved_at": retrieved_at,
224
+ "parameters": {
225
+ "period": args.period,
226
+ "interval": args.interval,
227
+ "start": self._format_datetime(args.start),
228
+ "end": self._format_datetime(args.end),
229
+ "auto_adjust": args.auto_adjust,
230
+ "include_actions": args.include_actions,
231
+ },
232
+ "records": records,
233
+ }
234
+
235
+ def _get_financials(
236
+ self, ticker: yf.Ticker, args: YFinanceArgs, retrieved_at: str
237
+ ) -> Dict[str, Any]:
238
+ datasets = {
239
+ "financials": getattr(ticker, "financials", None),
240
+ "quarterly_financials": getattr(ticker, "quarterly_financials", None),
241
+ "balance_sheet": getattr(ticker, "balance_sheet", None),
242
+ "quarterly_balance_sheet": getattr(ticker, "quarterly_balance_sheet", None),
243
+ "cashflow": getattr(ticker, "cashflow", None),
244
+ "quarterly_cashflow": getattr(ticker, "quarterly_cashflow", None),
245
+ }
246
+
247
+ serialized = {
248
+ name: (
249
+ self._serialize_dataframe(df)
250
+ if df is not None and not df.empty
251
+ else {}
252
+ )
253
+ for name, df in datasets.items()
254
+ }
255
+
256
+ return {
257
+ "ticker": args.ticker,
258
+ "retrieved_at": retrieved_at,
259
+ "financials": serialized,
260
+ }
261
+
262
+ @staticmethod
263
+ def _format_datetime(value: Optional[Union[datetime, str]]) -> Optional[str]:
264
+ if value is None:
265
+ return None
266
+ return value.isoformat() if isinstance(value, datetime) else str(value)
267
+
268
+ @staticmethod
269
+ def _to_native_number(value: Any) -> Optional[float]:
270
+ if value is None:
271
+ return None
272
+ if isinstance(value, (int, float)):
273
+ return float(value)
274
+ if isinstance(value, np.generic):
275
+ return float(value.item())
276
+ try:
277
+ return float(value)
278
+ except (TypeError, ValueError):
279
+ return None
280
+
281
+ def _clean_value(self, value: Any) -> Any:
282
+ if isinstance(value, np.generic):
283
+ return value.item()
284
+ if isinstance(value, (pd.Timestamp, datetime)):
285
+ return value.isoformat()
286
+ if isinstance(value, (bytes, bytearray)):
287
+ return value.decode("utf-8", errors="ignore")
288
+ if isinstance(value, (list, tuple)):
289
+ return [self._clean_value(item) for item in value]
290
+ if isinstance(value, dict):
291
+ return {str(k): self._clean_value(v) for k, v in value.items()}
292
+ return value
293
+
294
+ def _clean_nested(self, data: Dict[str, Any]) -> Dict[str, Any]:
295
+ return {str(k): self._clean_value(v) for k, v in data.items()}
296
+
297
+ def _serialize_dataframe(self, df: pd.DataFrame) -> Dict[str, Dict[str, Any]]:
298
+ cleaned_df = df.copy()
299
+ cleaned_df.index = cleaned_df.index.map(self._clean_value)
300
+ cleaned_df.columns = [self._clean_value(col) for col in cleaned_df.columns]
301
+ cleaned_df = cleaned_df.applymap(self._clean_value)
302
+ result: Dict[str, Dict[str, Any]] = {
303
+ str(column): {str(idx): val for idx, val in values.items()}
304
+ for column, values in cleaned_df.to_dict().items()
305
+ }
306
+ return result
@@ -0,0 +1,217 @@
1
+ """
2
+ ZipcodeAPI Toolkit - A unified toolkit for zipcode operations.
3
+ """
4
+ from typing import List, Dict, Any, Optional, Union
5
+ import httpx
6
+ from pydantic import BaseModel, Field
7
+ from navconfig import config
8
+ from .toolkit import AbstractToolkit
9
+ from .decorators import tool_schema
10
+
11
+
12
+ # Input schemas for different operations
13
+ class BasicZipcodeInput(BaseModel):
14
+ """Basic input schema for zipcode operations."""
15
+ zipcode: Union[str, int] = Field(description="The zipcode")
16
+ unit: Optional[str] = Field(description="Unit for coordinates (degrees, radians)", default="degrees")
17
+
18
+
19
+ class ZipcodeDistanceInput(BaseModel):
20
+ """Input schema for zipcode distance calculation."""
21
+ zipcode1: Union[str, int] = Field(description="The first zipcode")
22
+ zipcode2: Union[str, int] = Field(description="The second zipcode")
23
+ unit: Optional[str] = Field(description="Unit for coordinates (degrees, radians)", default="degrees")
24
+
25
+
26
+ class ZipcodeRadiusInput(BaseModel):
27
+ """Input schema for zipcode radius search."""
28
+ zipcode: Union[str, int] = Field(description="The center zipcode")
29
+ radius: int = Field(description="The radius in miles", default=5)
30
+ unit: Optional[str] = Field(description="Unit for coordinates (degrees, radians)", default="degrees")
31
+
32
+
33
+ class CityToZipcodesInput(BaseModel):
34
+ """Input schema for city to zipcodes lookup."""
35
+ city: str = Field(description="The city name")
36
+ state: str = Field(description="The state abbreviation (e.g., 'FL', 'CA')")
37
+
38
+
39
+ class ZipcodeAPIToolkit(AbstractToolkit):
40
+ """
41
+ Toolkit for interacting with ZipcodeAPI service.
42
+
43
+ Provides methods for:
44
+ - Getting zipcode location information
45
+ - Calculating distance between zipcodes
46
+ - Finding zipcodes within a radius
47
+ - Finding zipcodes for a city/state
48
+ """
49
+
50
+ def __init__(self, api_key: Optional[str] = None, **kwargs):
51
+ """
52
+ Initialize the ZipcodeAPI toolkit.
53
+
54
+ Args:
55
+ api_key: ZipcodeAPI key. If None, will use config.get('ZIPCODE_API_KEY')
56
+ **kwargs: Additional toolkit configuration
57
+ """
58
+ super().__init__(**kwargs)
59
+ self.api_key = api_key or config.get('ZIPCODE_API_KEY')
60
+ if not self.api_key:
61
+ raise ValueError(
62
+ "ZipcodeAPI key is required. Set ZIPCODE_API_KEY in config or pass api_key parameter."
63
+ )
64
+
65
+ @tool_schema(BasicZipcodeInput)
66
+ async def get_zipcode_location(self, zipcode: Union[str, int], unit: str = "degrees") -> Dict[str, Any]:
67
+ """
68
+ Get geographical information for a zipcode including city, state, latitude, longitude, and timezone.
69
+
70
+ Args:
71
+ zipcode: The zipcode to lookup
72
+ unit: Unit for coordinates (degrees, radians)
73
+
74
+ Returns:
75
+ Dictionary with location information
76
+ """
77
+ url = f"https://www.zipcodeapi.com/rest/{self.api_key}/info.json/{zipcode}/{unit}"
78
+
79
+ try:
80
+ async with httpx.AsyncClient() as client:
81
+ response = await client.get(url)
82
+ response.raise_for_status()
83
+ return response.json()
84
+ except httpx.HTTPStatusError as e:
85
+ raise ValueError(f"Error fetching zipcode location for {zipcode}: {e}") from e
86
+
87
+ @tool_schema(ZipcodeDistanceInput)
88
+ async def calculate_zipcode_distance(
89
+ self,
90
+ zipcode1: Union[str, int],
91
+ zipcode2: Union[str, int],
92
+ unit: str = "mile"
93
+ ) -> Dict[str, Any]:
94
+ """
95
+ Calculate the distance between two zipcodes.
96
+
97
+ Args:
98
+ zipcode1: First zipcode
99
+ zipcode2: Second zipcode
100
+ unit: Unit of distance (mile, km)
101
+
102
+ Returns:
103
+ Dictionary with distance information
104
+ """
105
+ url = f"https://www.zipcodeapi.com/rest/{self.api_key}/distance.json/{zipcode1}/{zipcode2}/{unit}"
106
+
107
+ try:
108
+ async with httpx.AsyncClient() as client:
109
+ response = await client.get(url)
110
+ response.raise_for_status()
111
+ return response.json()
112
+ except httpx.HTTPStatusError as e:
113
+ raise ValueError(f"Error calculating distance between {zipcode1} and {zipcode2}: {e}") from e
114
+
115
+ @tool_schema(ZipcodeRadiusInput)
116
+ async def find_zipcodes_in_radius(
117
+ self,
118
+ zipcode: Union[str, int],
119
+ radius: int = 5,
120
+ unit: str = "mile"
121
+ ) -> Dict[str, Any]:
122
+ """
123
+ Find all zipcodes within a given radius of a center zipcode.
124
+
125
+ Args:
126
+ zipcode: Center zipcode
127
+ radius: Search radius
128
+ unit: Unit of distance (mile, km)
129
+
130
+ Returns:
131
+ Dictionary with list of zipcodes in radius
132
+ """
133
+ url = f"https://www.zipcodeapi.com/rest/{self.api_key}/radius.json/{zipcode}/{radius}/{unit}"
134
+
135
+ try:
136
+ async with httpx.AsyncClient() as client:
137
+ response = await client.get(url)
138
+ response.raise_for_status()
139
+ return response.json()
140
+ except httpx.HTTPStatusError as e:
141
+ raise ValueError(f"Error finding zipcodes within {radius} {unit}s of {zipcode}: {e}") from e
142
+
143
+ @tool_schema(CityToZipcodesInput)
144
+ async def get_city_zipcodes(self, city: str, state: str) -> Dict[str, Any]:
145
+ """
146
+ Get all zipcodes for a given city and state.
147
+
148
+ Args:
149
+ city: City name
150
+ state: State abbreviation (e.g., 'FL', 'CA')
151
+
152
+ Returns:
153
+ Dictionary with list of zipcodes for the city
154
+ """
155
+ url = f"https://www.zipcodeapi.com/rest/{self.api_key}/city-zips.json/{city}/{state}"
156
+
157
+ try:
158
+ async with httpx.AsyncClient() as client:
159
+ response = await client.get(url)
160
+ response.raise_for_status()
161
+ return response.json()
162
+ except httpx.HTTPStatusError as e:
163
+ raise ValueError(f"Error getting zipcodes for {city}, {state}: {e}") from e
164
+
165
+ async def get_multiple_locations(
166
+ self,
167
+ zipcodes: List[Union[str, int]],
168
+ unit: str = "degrees"
169
+ ) -> Dict[str, Any]:
170
+ """
171
+ Get location information for multiple zipcodes.
172
+
173
+ Args:
174
+ zipcodes: List of zipcodes to lookup
175
+ unit: Unit for coordinates
176
+
177
+ Returns:
178
+ Dictionary mapping zipcodes to their location info
179
+ """
180
+ results = {}
181
+
182
+ async with httpx.AsyncClient() as client:
183
+ for zipcode in zipcodes:
184
+ try:
185
+ url = f"https://www.zipcodeapi.com/rest/{self.api_key}/info.json/{zipcode}/{unit}"
186
+ response = await client.get(url)
187
+ response.raise_for_status()
188
+ results[str(zipcode)] = response.json()
189
+ except httpx.HTTPStatusError as e:
190
+ results[str(zipcode)] = {"error": f"Failed to fetch: {e}"}
191
+
192
+ return {"results": results}
193
+
194
+ async def validate_zipcode(self, zipcode: Union[str, int]) -> Dict[str, Any]:
195
+ """
196
+ Validate if a zipcode exists and return basic info.
197
+
198
+ Args:
199
+ zipcode: Zipcode to validate
200
+
201
+ Returns:
202
+ Dictionary with validation result and basic info if valid
203
+ """
204
+ try:
205
+ result = await self.get_zipcode_location(zipcode)
206
+ return {
207
+ "valid": True,
208
+ "zipcode": zipcode,
209
+ "city": result.get("city"),
210
+ "state": result.get("state")
211
+ }
212
+ except ValueError:
213
+ return {
214
+ "valid": False,
215
+ "zipcode": zipcode,
216
+ "error": "Invalid zipcode"
217
+ }
@@ -0,0 +1,2 @@
1
+ from .types import SafeDict # pylint: disable=no-name-in-module
2
+ from .toml import parse_toml_config
@@ -0,0 +1,73 @@
1
+ from typing import Any, Optional
2
+ import inspect
3
+ from aiohttp import web
4
+
5
+ class RequestContext:
6
+ """RequestContext.
7
+
8
+ This class is a context manager for handling request-specific data.
9
+ It is designed to be used with the `async with` statement to ensure
10
+ proper setup and teardown of resources.
11
+
12
+ Attributes:
13
+ request (web.Request): The incoming web request.
14
+ app (Optional[Any]): An optional application context.
15
+ llm (Optional[Any]): An optional language model instance.
16
+ kwargs (dict): Additional keyword arguments for customization.
17
+ """
18
+
19
+ def __init__(
20
+ self,
21
+ request: web.Request = None,
22
+ app: Optional[Any] = None,
23
+ llm: Optional[Any] = None,
24
+ **kwargs
25
+ ):
26
+ """Initialize the RequestContext with the given parameters."""
27
+ self.request = request
28
+ self.app = app
29
+ self.llm = llm
30
+ self.kwargs = kwargs
31
+
32
+ async def __aenter__(self):
33
+ return self
34
+
35
+ async def __aexit__(self, exc_type, exc_value, traceback):
36
+ pass
37
+
38
+
39
+ class RequestBot:
40
+ """RequestBot.
41
+
42
+ This class is a wrapper around the AbstractBot to provide request-specific context.
43
+ """
44
+ def __init__(self, delegate: Any, context: RequestContext):
45
+ self.delegate = delegate
46
+ self.ctx = context
47
+
48
+ def __getattr__(self, name: str):
49
+ attr = getattr(self.delegate, name)
50
+ # If the attribute is a callable method (and not just a property)
51
+ if callable(attr):
52
+ # Check if the original method is async
53
+ if inspect.iscoroutinefunction(attr):
54
+ # Return a new ASYNC function that wraps the original
55
+ async def async_wrapper(*args, **kwargs):
56
+ # Inject the context into the call
57
+ if 'ctx' not in kwargs:
58
+ kwargs['ctx'] = self.ctx
59
+ # Await the original async method with the modified arguments
60
+ return await attr(*args, **kwargs)
61
+ return async_wrapper
62
+ else:
63
+ # Return a new SYNC function that wraps the original
64
+ def sync_wrapper(*args, **kwargs):
65
+ # Inject the context into the call
66
+ if 'ctx' not in kwargs:
67
+ kwargs['ctx'] = self.ctx
68
+ # Call the original sync method with the modified arguments
69
+ return attr(*args, **kwargs)
70
+ return sync_wrapper
71
+ else:
72
+ # If it's a simple attribute (e.g., self.delegate.name), return it directly
73
+ return attr
@@ -0,0 +1,5 @@
1
+ from .toml import TOMLParser
2
+
3
+ __all__ = (
4
+ 'TOMLParser',
5
+ )