WIP: building frontend; linkng pages to form backends

This commit is contained in:
Francis Secada 2025-01-20 22:16:04 -05:00
parent c281fd686e
commit 1e371613dc
23 changed files with 331 additions and 77 deletions

View File

@ -2,15 +2,33 @@ repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0 rev: v5.0.0
hooks: hooks:
- id: check-added-large-files
args: ['--maxkb=5000']
- id: check-ast - id: check-ast
- id: check-builtin-literals
- id: check-byte-order-marker
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-json - id: check-json
- id: check-merge-conflict - id: check-merge-conflict
# - id: check-shebang-scripts-are-executable
- id: check-symlinks
- id: check-toml
- id: check-vcs-permalinks
- id: check-xml
- id: check-yaml - id: check-yaml
- id: check-builtin-literals
- id: debug-statements - id: debug-statements
exclude: tests/
- id: destroyed-symlinks - id: destroyed-symlinks
# - id: detect-aws-credentials
- id: detect-private-key
- id: end-of-file-fixer - id: end-of-file-fixer
- id: mixed-line-ending exclude: tests/test_changes/
files: \.(py|sh|rst|yml|yaml)$
- id: pretty-format-json
args: [--autofix]
- id: sort-simple-yaml
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/aufdenpunkt/pre-commit-js-beautify - repo: https://github.com/aufdenpunkt/pre-commit-js-beautify
rev: 1.13.0 # represents the used version of JS Beautify as well rev: 1.13.0 # represents the used version of JS Beautify as well

View File

@ -17,6 +17,8 @@ jinjax
loguru loguru
lxml lxml
lxml[html_clean] lxml[html_clean]
openai
praw
python-dateutil python-dateutil
python-decouple python-decouple
python-slugify python-slugify

View File

@ -195,8 +195,10 @@ mistralai==1.3.1
# via pydantic-ai-slim # via pydantic-ai-slim
mypy-extensions==1.0.0 mypy-extensions==1.0.0
# via typing-inspect # via typing-inspect
openai==1.59.8 openai==1.59.9
# via pydantic-ai-slim # via
# -r core_requirements.in
# pydantic-ai-slim
opentelemetry-api==1.29.0 opentelemetry-api==1.29.0
# via # via
# opentelemetry-exporter-otlp-proto-http # opentelemetry-exporter-otlp-proto-http
@ -254,11 +256,15 @@ packaging==24.2
# via opentelemetry-instrumentation # via opentelemetry-instrumentation
parse==1.20.2 parse==1.20.2
# via httpx-html # via httpx-html
praw==7.8.1
# via -r core_requirements.in
prawcore==2.4.0
# via praw
priority==2.0.0 priority==2.0.0
# via hypercorn # via hypercorn
prometheus-client==0.21.1 prometheus-client==0.21.1
# via flower # via flower
prompt-toolkit==3.0.48 prompt-toolkit==3.0.50
# via click-repl # via click-repl
protobuf==5.29.3 protobuf==5.29.3
# via # via
@ -334,7 +340,9 @@ redis==5.2.1
requests==2.32.3 requests==2.32.3
# via # via
# opentelemetry-exporter-otlp-proto-http # opentelemetry-exporter-otlp-proto-http
# prawcore
# pydantic-ai-slim # pydantic-ai-slim
# update-checker
rich==13.9.4 rich==13.9.4
# via # via
# logfire # logfire
@ -410,6 +418,8 @@ tzdata==2024.2
# celery # celery
# kombu # kombu
# psycopg # psycopg
update-checker==0.18.0
# via praw
urllib3==1.26.20 urllib3==1.26.20
# via # via
# pyppeteer # pyppeteer
@ -429,6 +439,8 @@ wcwidth==0.2.13
# via prompt-toolkit # via prompt-toolkit
webencodings==0.5.1 webencodings==0.5.1
# via html5lib # via html5lib
websocket-client==1.8.0
# via praw
websockets==10.4 websockets==10.4
# via pyppeteer # via pyppeteer
win32-setctime==1.2.0 win32-setctime==1.2.0

View File

@ -2,7 +2,7 @@
alembic alembic
black black
fastapi-debug-toolbar fastapi-debug-toolbar @ git+https://github.com/fsecada01/fastapi-debug-toolbar.git@patch-2
isort isort
jupyterlab jupyterlab
jupyterlab-code-formatter jupyterlab-code-formatter

View File

@ -1,6 +1,6 @@
# This file was autogenerated by uv via the following command: # This file was autogenerated by uv via the following command:
# uv pip compile --strip-extras dev_requirements.in -o dev_requirements.txt # uv pip compile --strip-extras dev_requirements.in -o dev_requirements.txt
alembic==1.14.0 alembic==1.14.1
# via -r dev_requirements.in # via -r dev_requirements.in
annotated-types==0.7.0 annotated-types==0.7.0
# via # via
@ -80,7 +80,7 @@ fastapi==0.115.6
# via # via
# -c core_requirements.txt # -c core_requirements.txt
# fastapi-debug-toolbar # fastapi-debug-toolbar
fastapi-debug-toolbar==0.6.3 fastapi-debug-toolbar @ git+https://github.com/fsecada01/fastapi-debug-toolbar.git@2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4
# via -r dev_requirements.in # via -r dev_requirements.in
fastjsonschema==2.21.1 fastjsonschema==2.21.1
# via nbformat # via nbformat
@ -104,7 +104,7 @@ httpx==0.28.1
# via # via
# -c core_requirements.txt # -c core_requirements.txt
# jupyterlab # jupyterlab
identify==2.6.5 identify==2.6.6
# via pre-commit # via pre-commit
idna==3.10 idna==3.10
# via # via
@ -233,13 +233,13 @@ platformdirs==4.3.6
# black # black
# jupyter-core # jupyter-core
# virtualenv # virtualenv
pre-commit==4.0.1 pre-commit==4.1.0
# via -r dev_requirements.in # via -r dev_requirements.in
prometheus-client==0.21.1 prometheus-client==0.21.1
# via # via
# -c core_requirements.txt # -c core_requirements.txt
# jupyter-server # jupyter-server
prompt-toolkit==3.0.48 prompt-toolkit==3.0.50
# via # via
# -c core_requirements.txt # -c core_requirements.txt
# ipython # ipython
@ -412,4 +412,6 @@ webencodings==0.5.1
# bleach # bleach
# tinycss2 # tinycss2
websocket-client==1.8.0 websocket-client==1.8.0
# via jupyter-server # via
# -c core_requirements.txt
# jupyter-server

View File

@ -58,6 +58,7 @@ line_length = 80
[tool.uv.sources] [tool.uv.sources]
sqlmodel-crud-utilities = { git = "https://github.com/fsecada01/SQLModel-CRUD-Utilities", rev = "83e964f6e7b633e339e45ddcaaa49cd8617fa105" } sqlmodel-crud-utilities = { git = "https://github.com/fsecada01/SQLModel-CRUD-Utilities", rev = "83e964f6e7b633e339e45ddcaaa49cd8617fa105" }
fastapi-debug-toolbar = { git = "https://github.com/fsecada01/fastapi-debug-toolbar.git", rev = "2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4" }
#multi_line_output = 3 #multi_line_output = 3
#include_trailing_comma = true #include_trailing_comma = true
#force_grid_wrap = 0 #force_grid_wrap = 0
@ -140,7 +141,7 @@ dependencies = [
"mdurl==0.1.2", "mdurl==0.1.2",
"mistralai==1.3.1", "mistralai==1.3.1",
"mypy-extensions==1.0.0", "mypy-extensions==1.0.0",
"openai==1.59.8", "openai==1.59.9",
"opentelemetry-api==1.29.0", "opentelemetry-api==1.29.0",
"opentelemetry-exporter-otlp-proto-common==1.29.0", "opentelemetry-exporter-otlp-proto-common==1.29.0",
"opentelemetry-exporter-otlp-proto-http==1.29.0", "opentelemetry-exporter-otlp-proto-http==1.29.0",
@ -156,9 +157,11 @@ dependencies = [
"opentelemetry-util-http==0.50b0", "opentelemetry-util-http==0.50b0",
"packaging==24.2", "packaging==24.2",
"parse==1.20.2", "parse==1.20.2",
"praw==7.8.1",
"prawcore==2.4.0",
"priority==2.0.0", "priority==2.0.0",
"prometheus-client==0.21.1", "prometheus-client==0.21.1",
"prompt-toolkit==3.0.48", "prompt-toolkit==3.0.50",
"protobuf==5.29.3", "protobuf==5.29.3",
"psutil==5.9.8", "psutil==5.9.8",
"psycopg==3.2.4", "psycopg==3.2.4",
@ -201,12 +204,14 @@ dependencies = [
"typing-extensions==4.12.2", "typing-extensions==4.12.2",
"typing-inspect==0.9.0", "typing-inspect==0.9.0",
"tzdata==2024.2", "tzdata==2024.2",
"update-checker==0.18.0",
"urllib3==1.26.20", "urllib3==1.26.20",
"uvicorn==0.34.0", "uvicorn==0.34.0",
"vine==5.1.0", "vine==5.1.0",
"w3lib==2.2.1", "w3lib==2.2.1",
"wcwidth==0.2.13", "wcwidth==0.2.13",
"webencodings==0.5.1", "webencodings==0.5.1",
"websocket-client==1.8.0",
"websockets==10.4", "websockets==10.4",
"win32-setctime==1.2.0", "win32-setctime==1.2.0",
"wrapt==1.17.2", "wrapt==1.17.2",
@ -218,7 +223,8 @@ dependencies = [
[dependency-groups] [dependency-groups]
dev = [ dev = [
"alembic==1.14.0", "aiofiles==24.1.0",
"alembic==1.14.1",
"annotated-types==0.7.0", "annotated-types==0.7.0",
"anyio==4.8.0", "anyio==4.8.0",
"argon2-cffi-bindings==21.2.0", "argon2-cffi-bindings==21.2.0",
@ -252,7 +258,7 @@ dev = [
"h11==0.14.0", "h11==0.14.0",
"httpcore==1.0.7", "httpcore==1.0.7",
"httpx==0.28.1", "httpx==0.28.1",
"identify==2.6.5", "identify==2.6.6",
"idna==3.10", "idna==3.10",
"ipykernel==6.29.5", "ipykernel==6.29.5",
"ipython==8.31.0", "ipython==8.31.0",
@ -291,9 +297,9 @@ dev = [
"parso==0.8.4", "parso==0.8.4",
"pathspec==0.12.1", "pathspec==0.12.1",
"platformdirs==4.3.6", "platformdirs==4.3.6",
"pre-commit==4.0.1", "pre-commit==4.1.0",
"prometheus-client==0.21.1", "prometheus-client==0.21.1",
"prompt-toolkit==3.0.48", "prompt-toolkit==3.0.50",
"psutil==5.9.8", "psutil==5.9.8",
"pure-eval==0.2.3", "pure-eval==0.2.3",
"pycparser==2.22", "pycparser==2.22",

View File

@ -61,6 +61,7 @@ async def unicorn_exception_handler(request: Request, exc: UnicornException):
:param exc: UnicornException :param exc: UnicornException
:return: JSONResponse :return: JSONResponse
""" """
logger.error(f"{request}: {exc.name}")
return JSONResponse( return JSONResponse(
status_code=418, status_code=418,
content={ content={
@ -84,19 +85,21 @@ app.add_middleware(
https_only=get_val("HTTPS_ONLY", False), https_only=get_val("HTTPS_ONLY", False),
) )
app.include_router(user_frontend)
@user_frontend.get("/", response_class=HTMLResponse)
@app.get("/", response_class=HTMLResponse)
async def home_page(request: Request) -> HTMLResponse: async def home_page(request: Request) -> HTMLResponse:
""" """
default homepage for the web application default homepage for the web application
:param request: :param request:
:return: HTMLResponse :return: HTMLResponse
""" """
return templates.TemplateResponse("home.html", {"request": request}) return templates.TemplateResponse(
request, "home.html", context={"request": request}
)
app.include_router(user_frontend)
if app_settings.DEBUG in (True, "True"): if app_settings.DEBUG in (True, "True"):
from debug_toolbar.middleware import DebugToolbarMiddleware from debug_toolbar.middleware import DebugToolbarMiddleware
from debug_toolbar.panels.sqlalchemy import SQLAlchemyPanel from debug_toolbar.panels.sqlalchemy import SQLAlchemyPanel
@ -114,7 +117,7 @@ if app_settings.DEBUG in (True, "True"):
async def add_engines(self, request: Request): async def add_engines(self, request: Request):
""" """
Adding SQLModel engine to middleware object. Adding SQLModel engine to middleware object.
:param request: Request :param request: Request0
:return: :return:
""" """
self.engines.add(engine.sync_engine) self.engines.add(engine.sync_engine)

View File

@ -1,11 +1,15 @@
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass
from typing import Any from typing import Any
import openai
import praw
from pydantic_ai import Agent from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.models.openai import OpenAIModel
from backend.core.consts import AI_MODEL, default_system_prompt from backend.core.consts import AI_MODEL, default_system_prompt
from backend.db.base import Base from backend.db.base import Base
from backend.logger import logger
from backend.utils import get_val from backend.utils import get_val
@ -19,13 +23,49 @@ class SwotAnalysis(Base):
analysis: str analysis: str
class SwotAgentDeps(Base): def get_reddit_client(
user_agent: str, check_for_async: bool = False
) -> praw.Reddit | None:
"""
A function to return a reddit client, provided all env vars are loaded.
:param user_agent: str
:param check_for_async: bool = False
:return: praw.Reddit | None
"""
try:
reddit: praw.Reddit = praw.Reddit(
client_id=get_val("REDDIT_CLIENT_ID"),
client_secret=get_val("REDDIT_CLIENT_SECRET"),
user_agent=user_agent,
check_for_async=check_for_async,
)
except ValueError as e:
reddit = None
logger.info(
f"Reddit client not initialized. Please set the "
f"REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET environment. "
f"Also please note the error: {e} "
)
return reddit
@dataclass
class SwotAgentDeps:
"""Agent Dependencies for SWOT Analysis""" """Agent Dependencies for SWOT Analysis"""
request: Any | None = None request: Any | None = None
update_status_func: Callable | None = None update_status_func: Callable | None = None
tool_history: list[str] | None = None tool_history: list[str] | None = None
reddit_client: praw.Reddit | None = get_reddit_client(
user_agent=get_val("REDDIT_USER_AGENT"), check_for_async=False
)
client = openai.Client(api_key=get_val("OPENAI_API_KEY"))
swot_agent = Agent( swot_agent = Agent(
OpenAIModel(model_name=AI_MODEL, api_key=get_val("OPENAI_API_KEY")), OpenAIModel(model_name=AI_MODEL, api_key=get_val("OPENAI_API_KEY")),

View File

@ -2,10 +2,10 @@ import asyncio
import os import os
from fastapi import APIRouter, Form, Request from fastapi import APIRouter, Form, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from jinjax import Catalog, JinjaX from jinjax import Catalog, JinjaX
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
from starlette.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from backend.logger import logger from backend.logger import logger
from backend.settings import app_settings from backend.settings import app_settings
@ -39,7 +39,7 @@ user_frontend.mount(
) )
@user_frontend.post("analyze", response_class=HTMLResponse) @user_frontend.post("/analyze", response_class=HTMLResponse)
async def analyze_url(request: Request, url: str = Form(...)) -> HTMLResponse: async def analyze_url(request: Request, url: str = Form(...)) -> HTMLResponse:
""" """
Analyze a given URL using SWOT analysis agent Analyze a given URL using SWOT analysis agent

View File

@ -3,6 +3,32 @@ import os
from decouple import config from decouple import config
class ContextManager:
"""
Context middleware to inject all variables into the global context
object. This will ensure that the `request` object is available to all
components in JinjaX and removes the need to pass it through explicitly.
"""
def __init__(self):
self.global_context = {}
def set_context(self, **kwargs):
"""
Sets the global context for the application via kwargs
:param kwargs: dict[str, Any]
"""
self.global_context.update(kwargs)
def get_context(self):
"""
retrieves the global context for the application
:return: dict[str, Any]
"""
return self.global_context
def get_db_url(env: str = "dev"): def get_db_url(env: str = "dev"):
""" """

View File

@ -0,0 +1,28 @@
{# def
form_id: str,
action: str,
target: str,
method: str = 'GET'
#}
<div class="container">
<form id="{{ form_id }}"
{% if method.lower() == 'get' %}
hx-get={{ action }}
{% elif method.lower() == 'post' %}
hx-post={{ action }}
{% elif method.lower() == 'put' %}
hx-put={{ action }}
{% elif method.lower() == 'delete' %}
hx-delete={{ action }}
{% endif %}
hx-target="#{{ target }}">
{{ content }}
<div class="field">
<div class="control">
<input type="submit"
class="button is-success"
value="submit">
</div>
</div>
</form>
</div>

View File

@ -0,0 +1,21 @@
{# def
form_id: str,
action: str,
target: str,
method: str = 'GET'
#}
<Form form_id={{ form_id }}
action={{ action }}
target={{ target }}
method={{ method }}>
<div class="control">
<label for="search"
class="label">Search</label>
<input type="url"
class="input is-rounded"
id="search"
name="search"
placeholder="URL" />
</div>
{{ content }}
</Form>

View File

@ -3,17 +3,6 @@
<Header title="Pygentic AI"> <Header title="Pygentic AI">
<meta http-equiv="X-UA-Compatible" <meta http-equiv="X-UA-Compatible"
content="IE-edge, chrome=1"> content="IE-edge, chrome=1">
<Css url="{{ url_for('static', path='/css/bulma.min.css') }}"></Css>
<Css url="{{ url_for('static', path='/css/bulma-calendar.min.css') }}">
</Css>
<Css url="{{ url_for('static', path='/css/bulmatags-input.min-css') }}">
</Css>
<Css
url="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
</Css>
</Header> </Header>
<body> <body>

View File

@ -9,4 +9,5 @@
<title>{{ title }}</title> <title>{{ title }}</title>
{{ content }} {{ content }}
<Stylesheets></Stylesheets> <Stylesheets></Stylesheets>
{% include 'style_sheets.html' %}
</head> </head>

View File

@ -1,9 +1,11 @@
<Css url="{{ url_for('static', path='css/bulma.min.css') }}"></Css> <link rel="stylesheet"
<Css url="{{ url_for('static', path='css/bulma.css.map') }}"></Css> href="{{ url_for('static', path='css/bulma.min.css') }}">
<Css url="{{ url_for('static', path='css/bulma-collapsible.css') }}"></Css> <link rel="stylesheet"
<Css href="{{ url_for('static', path='css/bulma.css.map') }}">
url="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"> <link rel="stylesheet"
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" href="{{ url_for('static', path='css/bulma-collapsible.css') }}">
crossorigin="anonymous" <link rel="stylesheet"
referrerpolicy="no-referrer" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
</Css> integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
crossorigin="anonymous"
referrerpolicy="no-referrer">

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include "components/main/header.html" %}
{% block css_content %}
{% endblock css_content %}
</head>
<body>
{% include "components/main/nav.html" %}
{% block content%}
{% endblock %}
{% block js_content %}
{% endblock js_content %}
{% include "components/snippets/js.html" %}
</body>
</html>

View File

@ -0,0 +1,7 @@
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>{% block title %}Pygentic AI{% endblock title %}</title>
{% block head_content %}
{% endblock head_content %}
{% include 'components/main/style_sheets.html' %}

View File

@ -0,0 +1,11 @@
<link rel="stylesheet"
href="{{ url_for('static', path='css/bulma.min.css') }}">
<link rel="stylesheet"
href="{{ url_for('static', path='css/bulma.css.map') }}">
<link rel="stylesheet"
href="{{ url_for('static', path='css/bulma-collapsible.min.css') }}">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
crossorigin="anonymous"
referrerpolicy="no-referrer">

View File

@ -0,0 +1,6 @@
<script type="modules"
src="{{ url_for('static', path='/js/htmx.js') }}"></script>
<script src="{{ url_for('static', path='/js/jquery.min.js') }}"></script>
<script src="{{ url_for('static', path='/js/bulma.js') }}"></script>
<script src="{{ url_for('static', path='/js/bulma-collapsible.min.js') }}">
</script>

View File

@ -1,3 +1,20 @@
<Base> {% extends "components/main/base.html" %}
<p>foo bar</p> {% block content %}
</Base> <section class="hero is-large is-info">
<div class="hero-body">
<p class="title">SWOT ANALYZER</p>
<p class="subtitle">Strengths, Weaknesses, Opportunities and Threats
breakdown, courtesy of Generative AI-driven insights.</p>
<p>Try it out now!</p>
</div>
</section>
<div class="container">
<h1 class="title">Search Here</h1>
<Search form_id="swotSearch"
action="/analyze"
target="swotAnalysis"
method="post"></Search>
</div>
{% endblock content %}

98
uv.lock generated
View File

@ -87,6 +87,8 @@ dependencies = [
{ name = "opentelemetry-util-http" }, { name = "opentelemetry-util-http" },
{ name = "packaging" }, { name = "packaging" },
{ name = "parse" }, { name = "parse" },
{ name = "praw" },
{ name = "prawcore" },
{ name = "priority" }, { name = "priority" },
{ name = "prometheus-client" }, { name = "prometheus-client" },
{ name = "prompt-toolkit" }, { name = "prompt-toolkit" },
@ -132,12 +134,14 @@ dependencies = [
{ name = "typing-extensions" }, { name = "typing-extensions" },
{ name = "typing-inspect" }, { name = "typing-inspect" },
{ name = "tzdata" }, { name = "tzdata" },
{ name = "update-checker" },
{ name = "urllib3" }, { name = "urllib3" },
{ name = "uvicorn" }, { name = "uvicorn" },
{ name = "vine" }, { name = "vine" },
{ name = "w3lib" }, { name = "w3lib" },
{ name = "wcwidth" }, { name = "wcwidth" },
{ name = "webencodings" }, { name = "webencodings" },
{ name = "websocket-client" },
{ name = "websockets" }, { name = "websockets" },
{ name = "win32-setctime" }, { name = "win32-setctime" },
{ name = "wrapt" }, { name = "wrapt" },
@ -149,6 +153,7 @@ dependencies = [
[package.dev-dependencies] [package.dev-dependencies]
dev = [ dev = [
{ name = "aiofiles" },
{ name = "alembic" }, { name = "alembic" },
{ name = "annotated-types" }, { name = "annotated-types" },
{ name = "anyio" }, { name = "anyio" },
@ -338,7 +343,7 @@ requires-dist = [
{ name = "mdurl", specifier = "==0.1.2" }, { name = "mdurl", specifier = "==0.1.2" },
{ name = "mistralai", specifier = "==1.3.1" }, { name = "mistralai", specifier = "==1.3.1" },
{ name = "mypy-extensions", specifier = "==1.0.0" }, { name = "mypy-extensions", specifier = "==1.0.0" },
{ name = "openai", specifier = "==1.59.8" }, { name = "openai", specifier = "==1.59.9" },
{ name = "opentelemetry-api", specifier = "==1.29.0" }, { name = "opentelemetry-api", specifier = "==1.29.0" },
{ name = "opentelemetry-exporter-otlp-proto-common", specifier = "==1.29.0" }, { name = "opentelemetry-exporter-otlp-proto-common", specifier = "==1.29.0" },
{ name = "opentelemetry-exporter-otlp-proto-http", specifier = "==1.29.0" }, { name = "opentelemetry-exporter-otlp-proto-http", specifier = "==1.29.0" },
@ -354,9 +359,11 @@ requires-dist = [
{ name = "opentelemetry-util-http", specifier = "==0.50b0" }, { name = "opentelemetry-util-http", specifier = "==0.50b0" },
{ name = "packaging", specifier = "==24.2" }, { name = "packaging", specifier = "==24.2" },
{ name = "parse", specifier = "==1.20.2" }, { name = "parse", specifier = "==1.20.2" },
{ name = "praw", specifier = "==7.8.1" },
{ name = "prawcore", specifier = "==2.4.0" },
{ name = "priority", specifier = "==2.0.0" }, { name = "priority", specifier = "==2.0.0" },
{ name = "prometheus-client", specifier = "==0.21.1" }, { name = "prometheus-client", specifier = "==0.21.1" },
{ name = "prompt-toolkit", specifier = "==3.0.48" }, { name = "prompt-toolkit", specifier = "==3.0.50" },
{ name = "protobuf", specifier = "==5.29.3" }, { name = "protobuf", specifier = "==5.29.3" },
{ name = "psutil", specifier = "==5.9.8" }, { name = "psutil", specifier = "==5.9.8" },
{ name = "psycopg", specifier = "==3.2.4" }, { name = "psycopg", specifier = "==3.2.4" },
@ -399,12 +406,14 @@ requires-dist = [
{ name = "typing-extensions", specifier = "==4.12.2" }, { name = "typing-extensions", specifier = "==4.12.2" },
{ name = "typing-inspect", specifier = "==0.9.0" }, { name = "typing-inspect", specifier = "==0.9.0" },
{ name = "tzdata", specifier = "==2024.2" }, { name = "tzdata", specifier = "==2024.2" },
{ name = "update-checker", specifier = "==0.18.0" },
{ name = "urllib3", specifier = "==1.26.20" }, { name = "urllib3", specifier = "==1.26.20" },
{ name = "uvicorn", specifier = "==0.34.0" }, { name = "uvicorn", specifier = "==0.34.0" },
{ name = "vine", specifier = "==5.1.0" }, { name = "vine", specifier = "==5.1.0" },
{ name = "w3lib", specifier = "==2.2.1" }, { name = "w3lib", specifier = "==2.2.1" },
{ name = "wcwidth", specifier = "==0.2.13" }, { name = "wcwidth", specifier = "==0.2.13" },
{ name = "webencodings", specifier = "==0.5.1" }, { name = "webencodings", specifier = "==0.5.1" },
{ name = "websocket-client", specifier = "==1.8.0" },
{ name = "websockets", specifier = "==10.4" }, { name = "websockets", specifier = "==10.4" },
{ name = "win32-setctime", specifier = "==1.2.0" }, { name = "win32-setctime", specifier = "==1.2.0" },
{ name = "wrapt", specifier = "==1.17.2" }, { name = "wrapt", specifier = "==1.17.2" },
@ -416,7 +425,8 @@ requires-dist = [
[package.metadata.requires-dev] [package.metadata.requires-dev]
dev = [ dev = [
{ name = "alembic", specifier = "==1.14.0" }, { name = "aiofiles", specifier = "==24.1.0" },
{ name = "alembic", specifier = "==1.14.1" },
{ name = "annotated-types", specifier = "==0.7.0" }, { name = "annotated-types", specifier = "==0.7.0" },
{ name = "anyio", specifier = "==4.8.0" }, { name = "anyio", specifier = "==4.8.0" },
{ name = "argon2-cffi", specifier = "==23.1.0" }, { name = "argon2-cffi", specifier = "==23.1.0" },
@ -442,7 +452,7 @@ dev = [
{ name = "distlib", specifier = "==0.3.9" }, { name = "distlib", specifier = "==0.3.9" },
{ name = "executing", specifier = "==2.1.0" }, { name = "executing", specifier = "==2.1.0" },
{ name = "fastapi", specifier = "==0.115.6" }, { name = "fastapi", specifier = "==0.115.6" },
{ name = "fastapi-debug-toolbar", specifier = "==0.6.3" }, { name = "fastapi-debug-toolbar", git = "https://github.com/fsecada01/fastapi-debug-toolbar.git?rev=2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4" },
{ name = "fastjsonschema", specifier = "==2.21.1" }, { name = "fastjsonschema", specifier = "==2.21.1" },
{ name = "filelock", specifier = "==3.16.1" }, { name = "filelock", specifier = "==3.16.1" },
{ name = "fqdn", specifier = "==1.5.1" }, { name = "fqdn", specifier = "==1.5.1" },
@ -450,7 +460,7 @@ dev = [
{ name = "h11", specifier = "==0.14.0" }, { name = "h11", specifier = "==0.14.0" },
{ name = "httpcore", specifier = "==1.0.7" }, { name = "httpcore", specifier = "==1.0.7" },
{ name = "httpx", specifier = "==0.28.1" }, { name = "httpx", specifier = "==0.28.1" },
{ name = "identify", specifier = "==2.6.5" }, { name = "identify", specifier = "==2.6.6" },
{ name = "idna", specifier = "==3.10" }, { name = "idna", specifier = "==3.10" },
{ name = "ipykernel", specifier = "==6.29.5" }, { name = "ipykernel", specifier = "==6.29.5" },
{ name = "ipython", specifier = "==8.31.0" }, { name = "ipython", specifier = "==8.31.0" },
@ -489,9 +499,9 @@ dev = [
{ name = "parso", specifier = "==0.8.4" }, { name = "parso", specifier = "==0.8.4" },
{ name = "pathspec", specifier = "==0.12.1" }, { name = "pathspec", specifier = "==0.12.1" },
{ name = "platformdirs", specifier = "==4.3.6" }, { name = "platformdirs", specifier = "==4.3.6" },
{ name = "pre-commit", specifier = "==4.0.1" }, { name = "pre-commit", specifier = "==4.1.0" },
{ name = "prometheus-client", specifier = "==0.21.1" }, { name = "prometheus-client", specifier = "==0.21.1" },
{ name = "prompt-toolkit", specifier = "==3.0.48" }, { name = "prompt-toolkit", specifier = "==3.0.50" },
{ name = "psutil", specifier = "==5.9.8" }, { name = "psutil", specifier = "==5.9.8" },
{ name = "pure-eval", specifier = "==0.2.3" }, { name = "pure-eval", specifier = "==0.2.3" },
{ name = "pycparser", specifier = "==2.22" }, { name = "pycparser", specifier = "==2.22" },
@ -561,16 +571,16 @@ wheels = [
[[package]] [[package]]
name = "alembic" name = "alembic"
version = "1.14.0" version = "1.14.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "mako" }, { name = "mako" },
{ name = "sqlalchemy" }, { name = "sqlalchemy" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/00/1e/8cb8900ba1b6360431e46fb7a89922916d3a1b017a8908a7c0499cc7e5f6/alembic-1.14.0.tar.gz", hash = "sha256:b00892b53b3642d0b8dbedba234dbf1924b69be83a9a769d5a624b01094e304b", size = 1916172 } sdist = { url = "https://files.pythonhosted.org/packages/99/09/f844822e4e847a3f0bd41797f93c4674cd4d2462a3f6c459aa528cdf786e/alembic-1.14.1.tar.gz", hash = "sha256:496e888245a53adf1498fcab31713a469c65836f8de76e01399aa1c3e90dd213", size = 1918219 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/06/8b505aea3d77021b18dcbd8133aa1418f1a1e37e432a465b14c46b2c0eaa/alembic-1.14.0-py3-none-any.whl", hash = "sha256:99bd884ca390466db5e27ffccff1d179ec5c05c965cfefc0607e69f9e411cb25", size = 233482 }, { url = "https://files.pythonhosted.org/packages/54/7e/ac0991d1745f7d755fc1cd381b3990a45b404b4d008fc75e2a983516fbfe/alembic-1.14.1-py3-none-any.whl", hash = "sha256:1acdd7a3a478e208b0503cd73614d5e4c6efafa4e73518bb60e4f2846a37b1c5", size = 233565 },
] ]
[[package]] [[package]]
@ -1100,7 +1110,7 @@ wheels = [
[[package]] [[package]]
name = "fastapi-debug-toolbar" name = "fastapi-debug-toolbar"
version = "0.6.3" version = "0.6.3"
source = { registry = "https://pypi.org/simple" } source = { git = "https://github.com/fsecada01/fastapi-debug-toolbar.git?rev=2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4#2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4" }
dependencies = [ dependencies = [
{ name = "anyio" }, { name = "anyio" },
{ name = "fastapi" }, { name = "fastapi" },
@ -1111,10 +1121,6 @@ dependencies = [
{ name = "pyinstrument" }, { name = "pyinstrument" },
{ name = "sqlparse" }, { name = "sqlparse" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/ac/e6/c228493e929eeb2b9e61806a63e78c3c0bec4e22ddee99f321ffba4fa64a/fastapi_debug_toolbar-0.6.3.tar.gz", hash = "sha256:15ff6828f9432c786af39f23a2d814ef2af516964b5a9a856444de135a78b2af", size = 26929 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a7/09/b01c8c60d608e93faa257a9a3fc9a9739c70c9ac926edfbbe92baebbf33b/fastapi_debug_toolbar-0.6.3-py3-none-any.whl", hash = "sha256:077b5ffeb10426c49387ef090cf307a316d5c71c69bbffe270d9898d2554429e", size = 42904 },
]
[[package]] [[package]]
name = "fastapi-restful" name = "fastapi-restful"
@ -1393,11 +1399,11 @@ wheels = [
[[package]] [[package]]
name = "identify" name = "identify"
version = "2.6.5" version = "2.6.6"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cf/92/69934b9ef3c31ca2470980423fda3d00f0460ddefdf30a67adf7f17e2e00/identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc", size = 99213 } sdist = { url = "https://files.pythonhosted.org/packages/82/bf/c68c46601bacd4c6fb4dd751a42b6e7087240eaabc6487f2ef7a48e0e8fc/identify-2.6.6.tar.gz", hash = "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251", size = 99217 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/fa/dce098f4cdf7621aa8f7b4f919ce545891f489482f0bfa5102f3eca8608b/identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566", size = 99078 }, { url = "https://files.pythonhosted.org/packages/74/a1/68a395c17eeefb04917034bd0a1bfa765e7654fa150cca473d669aa3afb5/identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881", size = 99083 },
] ]
[[package]] [[package]]
@ -2085,7 +2091,7 @@ wheels = [
[[package]] [[package]]
name = "openai" name = "openai"
version = "1.59.8" version = "1.59.9"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "anyio" }, { name = "anyio" },
@ -2097,9 +2103,9 @@ dependencies = [
{ name = "tqdm" }, { name = "tqdm" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/e0/c4/b4482784de63c7158f6c0afcb07fd66450ea6c912d6bddf9d7599f2eda25/openai-1.59.8.tar.gz", hash = "sha256:ac4bda5fa9819fdc6127e8ea8a63501f425c587244bc653c7c11a8ad84f953e1", size = 346775 } sdist = { url = "https://files.pythonhosted.org/packages/ec/2d/04faa92bac0341649223398503db4415d2f658a757d9d32bb68f3378ddd0/openai-1.59.9.tar.gz", hash = "sha256:ec1a20b0351b4c3e65c6292db71d8233515437c6065efd4fd50edeb55df5f5d2", size = 347134 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/8c/cf/5b235e12ead3cd2098f9792776c966994c1bc558cba5799e12f3045227df/openai-1.59.8-py3-none-any.whl", hash = "sha256:a8b8ee35c4083b88e6da45406d883cf6bd91a98ab7dd79178b8bc24c8bfb09d9", size = 455567 }, { url = "https://files.pythonhosted.org/packages/07/b4/57f1954a4560092ad8c45f07ad183eab9c8e093e0a1db829f9b506b2d5d1/openai-1.59.9-py3-none-any.whl", hash = "sha256:61a0608a1313c08ddf92fe793b6dbd1630675a1fe3866b2f96447ce30050c448", size = 455527 },
] ]
[[package]] [[package]]
@ -2358,9 +2364,35 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 },
] ]
[[package]]
name = "praw"
version = "7.8.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "prawcore" },
{ name = "update-checker" },
{ name = "websocket-client" },
]
sdist = { url = "https://files.pythonhosted.org/packages/4c/52/7dd0b3d9ccb78e90236420ef6c51b6d9b2400a7229442f0cfcf2258cce21/praw-7.8.1.tar.gz", hash = "sha256:3c5767909f71e48853eb6335fef7b50a43cbe3da728cdfb16d3be92904b0a4d8", size = 154106 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/73/ca/60ec131c3b43bff58261167045778b2509b83922ce8f935ac89d871bd3ea/praw-7.8.1-py3-none-any.whl", hash = "sha256:15917a81a06e20ff0aaaf1358481f4588449fa2421233040cb25e5c8202a3e2f", size = 189338 },
]
[[package]]
name = "prawcore"
version = "2.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8a/62/d4c99cf472205f1e5da846b058435a6a7c988abf8eb6f7d632a7f32f4a77/prawcore-2.4.0.tar.gz", hash = "sha256:b7b2b5a1d04406e086ab4e79988dc794df16059862f329f4c6a43ed09986c335", size = 15862 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/96/5c/8af904314e42d5401afcfaff69940dc448e974f80f7aa39b241a4fbf0cf1/prawcore-2.4.0-py3-none-any.whl", hash = "sha256:29af5da58d85704b439ad3c820873ad541f4535e00bb98c66f0fbcc8c603065a", size = 17203 },
]
[[package]] [[package]]
name = "pre-commit" name = "pre-commit"
version = "4.0.1" version = "4.1.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "cfgv" }, { name = "cfgv" },
@ -2369,9 +2401,9 @@ dependencies = [
{ name = "pyyaml" }, { name = "pyyaml" },
{ name = "virtualenv" }, { name = "virtualenv" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678 } sdist = { url = "https://files.pythonhosted.org/packages/2a/13/b62d075317d8686071eb843f0bb1f195eb332f48869d3c31a4c6f1e063ac/pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4", size = 193330 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, { url = "https://files.pythonhosted.org/packages/43/b3/df14c580d82b9627d173ceea305ba898dca135feb360b6d84019d0803d3b/pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b", size = 220560 },
] ]
[[package]] [[package]]
@ -2394,14 +2426,14 @@ wheels = [
[[package]] [[package]]
name = "prompt-toolkit" name = "prompt-toolkit"
version = "3.0.48" version = "3.0.50"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "wcwidth" }, { name = "wcwidth" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/2d/4f/feb5e137aff82f7c7f3248267b97451da3644f6cdc218edfe549fb354127/prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90", size = 424684 } sdist = { url = "https://files.pythonhosted.org/packages/a1/e1/bd15cb8ffdcfeeb2bdc215de3c3cffca11408d829e4b8416dcfe71ba8854/prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab", size = 429087 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a9/6a/fd08d94654f7e67c52ca30523a178b3f8ccc4237fce4be90d39c938a831a/prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e", size = 386595 }, { url = "https://files.pythonhosted.org/packages/e4/ea/d836f008d33151c7a1f62caf3d8dd782e4d15f6a43897f64480c2b8de2ad/prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198", size = 387816 },
] ]
[[package]] [[package]]
@ -3284,6 +3316,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 },
] ]
[[package]]
name = "update-checker"
version = "0.18.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5c/0b/1bec4a6cc60d33ce93d11a7bcf1aeffc7ad0aa114986073411be31395c6f/update_checker-0.18.0.tar.gz", hash = "sha256:6a2d45bb4ac585884a6b03f9eade9161cedd9e8111545141e9aa9058932acb13", size = 6699 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/ba/8dd7fa5f0b1c6a8ac62f8f57f7e794160c1f86f31c6d0fb00f582372a3e4/update_checker-0.18.0-py3-none-any.whl", hash = "sha256:cbba64760a36fe2640d80d85306e8fe82b6816659190993b7bdabadee4d4bbfd", size = 7008 },
]
[[package]] [[package]]
name = "uri-template" name = "uri-template"
version = "1.3.0" version = "1.3.0"