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
rev: v5.0.0
hooks:
- id: check-added-large-files
args: ['--maxkb=5000']
- 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-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-builtin-literals
- id: debug-statements
exclude: tests/
- id: destroyed-symlinks
# - id: detect-aws-credentials
- id: detect-private-key
- 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
- repo: https://github.com/aufdenpunkt/pre-commit-js-beautify
rev: 1.13.0 # represents the used version of JS Beautify as well

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
# This file was autogenerated by uv via the following command:
# 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
annotated-types==0.7.0
# via
@ -80,7 +80,7 @@ fastapi==0.115.6
# via
# -c core_requirements.txt
# 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
fastjsonschema==2.21.1
# via nbformat
@ -104,7 +104,7 @@ httpx==0.28.1
# via
# -c core_requirements.txt
# jupyterlab
identify==2.6.5
identify==2.6.6
# via pre-commit
idna==3.10
# via
@ -233,13 +233,13 @@ platformdirs==4.3.6
# black
# jupyter-core
# virtualenv
pre-commit==4.0.1
pre-commit==4.1.0
# via -r dev_requirements.in
prometheus-client==0.21.1
# via
# -c core_requirements.txt
# jupyter-server
prompt-toolkit==3.0.48
prompt-toolkit==3.0.50
# via
# -c core_requirements.txt
# ipython
@ -412,4 +412,6 @@ webencodings==0.5.1
# bleach
# tinycss2
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]
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
#include_trailing_comma = true
#force_grid_wrap = 0
@ -140,7 +141,7 @@ dependencies = [
"mdurl==0.1.2",
"mistralai==1.3.1",
"mypy-extensions==1.0.0",
"openai==1.59.8",
"openai==1.59.9",
"opentelemetry-api==1.29.0",
"opentelemetry-exporter-otlp-proto-common==1.29.0",
"opentelemetry-exporter-otlp-proto-http==1.29.0",
@ -156,9 +157,11 @@ dependencies = [
"opentelemetry-util-http==0.50b0",
"packaging==24.2",
"parse==1.20.2",
"praw==7.8.1",
"prawcore==2.4.0",
"priority==2.0.0",
"prometheus-client==0.21.1",
"prompt-toolkit==3.0.48",
"prompt-toolkit==3.0.50",
"protobuf==5.29.3",
"psutil==5.9.8",
"psycopg==3.2.4",
@ -201,12 +204,14 @@ dependencies = [
"typing-extensions==4.12.2",
"typing-inspect==0.9.0",
"tzdata==2024.2",
"update-checker==0.18.0",
"urllib3==1.26.20",
"uvicorn==0.34.0",
"vine==5.1.0",
"w3lib==2.2.1",
"wcwidth==0.2.13",
"webencodings==0.5.1",
"websocket-client==1.8.0",
"websockets==10.4",
"win32-setctime==1.2.0",
"wrapt==1.17.2",
@ -218,7 +223,8 @@ dependencies = [
[dependency-groups]
dev = [
"alembic==1.14.0",
"aiofiles==24.1.0",
"alembic==1.14.1",
"annotated-types==0.7.0",
"anyio==4.8.0",
"argon2-cffi-bindings==21.2.0",
@ -252,7 +258,7 @@ dev = [
"h11==0.14.0",
"httpcore==1.0.7",
"httpx==0.28.1",
"identify==2.6.5",
"identify==2.6.6",
"idna==3.10",
"ipykernel==6.29.5",
"ipython==8.31.0",
@ -291,9 +297,9 @@ dev = [
"parso==0.8.4",
"pathspec==0.12.1",
"platformdirs==4.3.6",
"pre-commit==4.0.1",
"pre-commit==4.1.0",
"prometheus-client==0.21.1",
"prompt-toolkit==3.0.48",
"prompt-toolkit==3.0.50",
"psutil==5.9.8",
"pure-eval==0.2.3",
"pycparser==2.22",

View File

@ -61,6 +61,7 @@ async def unicorn_exception_handler(request: Request, exc: UnicornException):
:param exc: UnicornException
:return: JSONResponse
"""
logger.error(f"{request}: {exc.name}")
return JSONResponse(
status_code=418,
content={
@ -84,19 +85,21 @@ app.add_middleware(
https_only=get_val("HTTPS_ONLY", False),
)
app.include_router(user_frontend)
@app.get("/", response_class=HTMLResponse)
@user_frontend.get("/", response_class=HTMLResponse)
async def home_page(request: Request) -> HTMLResponse:
"""
default homepage for the web application
:param request:
: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"):
from debug_toolbar.middleware import DebugToolbarMiddleware
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):
"""
Adding SQLModel engine to middleware object.
:param request: Request
:param request: Request0
:return:
"""
self.engines.add(engine.sync_engine)

View File

@ -1,11 +1,15 @@
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any
import openai
import praw
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel
from backend.core.consts import AI_MODEL, default_system_prompt
from backend.db.base import Base
from backend.logger import logger
from backend.utils import get_val
@ -19,13 +23,49 @@ class SwotAnalysis(Base):
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"""
request: Any | None = None
update_status_func: Callable | 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(
OpenAIModel(model_name=AI_MODEL, api_key=get_val("OPENAI_API_KEY")),

View File

@ -2,10 +2,10 @@ import asyncio
import os
from fastapi import APIRouter, Form, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from jinjax import Catalog, JinjaX
from starlette.responses import HTMLResponse
from starlette.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from backend.logger import logger
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:
"""
Analyze a given URL using SWOT analysis agent

View File

@ -3,6 +3,32 @@ import os
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"):
"""

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">
<meta http-equiv="X-UA-Compatible"
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>
<body>

View File

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

View File

@ -1,9 +1,11 @@
<Css url="{{ url_for('static', path='css/bulma.min.css') }}"></Css>
<Css url="{{ url_for('static', path='css/bulma.css.map') }}"></Css>
<Css url="{{ url_for('static', path='css/bulma-collapsible.css') }}"></Css>
<Css
url="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<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.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"
</Css>
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>
<p>foo bar</p>
</Base>
{% extends "components/main/base.html" %}
{% block content %}
<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 = "packaging" },
{ name = "parse" },
{ name = "praw" },
{ name = "prawcore" },
{ name = "priority" },
{ name = "prometheus-client" },
{ name = "prompt-toolkit" },
@ -132,12 +134,14 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "typing-inspect" },
{ name = "tzdata" },
{ name = "update-checker" },
{ name = "urllib3" },
{ name = "uvicorn" },
{ name = "vine" },
{ name = "w3lib" },
{ name = "wcwidth" },
{ name = "webencodings" },
{ name = "websocket-client" },
{ name = "websockets" },
{ name = "win32-setctime" },
{ name = "wrapt" },
@ -149,6 +153,7 @@ dependencies = [
[package.dev-dependencies]
dev = [
{ name = "aiofiles" },
{ name = "alembic" },
{ name = "annotated-types" },
{ name = "anyio" },
@ -338,7 +343,7 @@ requires-dist = [
{ name = "mdurl", specifier = "==0.1.2" },
{ name = "mistralai", specifier = "==1.3.1" },
{ 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-exporter-otlp-proto-common", 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 = "packaging", specifier = "==24.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 = "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 = "psutil", specifier = "==5.9.8" },
{ name = "psycopg", specifier = "==3.2.4" },
@ -399,12 +406,14 @@ requires-dist = [
{ name = "typing-extensions", specifier = "==4.12.2" },
{ name = "typing-inspect", specifier = "==0.9.0" },
{ name = "tzdata", specifier = "==2024.2" },
{ name = "update-checker", specifier = "==0.18.0" },
{ name = "urllib3", specifier = "==1.26.20" },
{ name = "uvicorn", specifier = "==0.34.0" },
{ name = "vine", specifier = "==5.1.0" },
{ name = "w3lib", specifier = "==2.2.1" },
{ name = "wcwidth", specifier = "==0.2.13" },
{ name = "webencodings", specifier = "==0.5.1" },
{ name = "websocket-client", specifier = "==1.8.0" },
{ name = "websockets", specifier = "==10.4" },
{ name = "win32-setctime", specifier = "==1.2.0" },
{ name = "wrapt", specifier = "==1.17.2" },
@ -416,7 +425,8 @@ requires-dist = [
[package.metadata.requires-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 = "anyio", specifier = "==4.8.0" },
{ name = "argon2-cffi", specifier = "==23.1.0" },
@ -442,7 +452,7 @@ dev = [
{ name = "distlib", specifier = "==0.3.9" },
{ name = "executing", specifier = "==2.1.0" },
{ 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 = "filelock", specifier = "==3.16.1" },
{ name = "fqdn", specifier = "==1.5.1" },
@ -450,7 +460,7 @@ dev = [
{ name = "h11", specifier = "==0.14.0" },
{ name = "httpcore", specifier = "==1.0.7" },
{ name = "httpx", specifier = "==0.28.1" },
{ name = "identify", specifier = "==2.6.5" },
{ name = "identify", specifier = "==2.6.6" },
{ name = "idna", specifier = "==3.10" },
{ name = "ipykernel", specifier = "==6.29.5" },
{ name = "ipython", specifier = "==8.31.0" },
@ -489,9 +499,9 @@ dev = [
{ name = "parso", specifier = "==0.8.4" },
{ name = "pathspec", specifier = "==0.12.1" },
{ 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 = "prompt-toolkit", specifier = "==3.0.48" },
{ name = "prompt-toolkit", specifier = "==3.0.50" },
{ name = "psutil", specifier = "==5.9.8" },
{ name = "pure-eval", specifier = "==0.2.3" },
{ name = "pycparser", specifier = "==2.22" },
@ -561,16 +571,16 @@ wheels = [
[[package]]
name = "alembic"
version = "1.14.0"
version = "1.14.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mako" },
{ name = "sqlalchemy" },
{ 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 = [
{ 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]]
@ -1100,7 +1110,7 @@ wheels = [
[[package]]
name = "fastapi-debug-toolbar"
version = "0.6.3"
source = { registry = "https://pypi.org/simple" }
source = { git = "https://github.com/fsecada01/fastapi-debug-toolbar.git?rev=2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4#2da9f1e724d1d7ca56990ba7a8e72598fa3e1cf4" }
dependencies = [
{ name = "anyio" },
{ name = "fastapi" },
@ -1111,10 +1121,6 @@ dependencies = [
{ name = "pyinstrument" },
{ 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]]
name = "fastapi-restful"
@ -1393,11 +1399,11 @@ wheels = [
[[package]]
name = "identify"
version = "2.6.5"
version = "2.6.6"
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 = [
{ 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]]
@ -2085,7 +2091,7 @@ wheels = [
[[package]]
name = "openai"
version = "1.59.8"
version = "1.59.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@ -2097,9 +2103,9 @@ dependencies = [
{ name = "tqdm" },
{ 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 = [
{ 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]]
@ -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 },
]
[[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]]
name = "pre-commit"
version = "4.0.1"
version = "4.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cfgv" },
@ -2369,9 +2401,9 @@ dependencies = [
{ name = "pyyaml" },
{ 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 = [
{ 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]]
@ -2394,14 +2426,14 @@ wheels = [
[[package]]
name = "prompt-toolkit"
version = "3.0.48"
version = "3.0.50"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ 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 = [
{ 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]]
@ -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 },
]
[[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]]
name = "uri-template"
version = "1.3.0"