[0.0.5] - 03-14-2024 Dialectic Agent (#38)
* 🧪 asyncify tests * ✨ asyncify client * Basic Test for Page based pagination * add sync buildstep and client * add vscode DX * Added Testing for generators and updated examples * feat: example updates * readme exists now * Stylistic changes and generic message * Metamessages with other refactoring - untested * Work with unit tests * Fix Examples * MEME-78 Update Changelogs * Docstrings to client * 🧪 autogenerate sync tests * test one * add db type * sync client * add status badge * add coverage * add file * give perms * properly output coverage * split test and coverage * rename action * 🧪 autogenerate sync tests (#16) * Vector Support (#18) * Scaffold for PGVector support * Buggy crud with logic skeleton on api * Crud logic and schema definition for pgvector * Populate all routes and refactor to name Collection * vince's progress * AsyncCollection progress * Local PGVector Docker Container * client methods for sdk except document delete and update * Vector Support Passing All Test Cases * Docs Updates --------- Co-authored-by: vintro <vince@plasticlabs.ai> * Add reverse parameters for paginated routes * Address dependabot * Formatting * initial commit on honcho dspy personas * working, hit token limit and can't test dspy optimization * initial version working, need to test optimization * optimizers working, but appending any example * ready for user object (tbomk) * Revert "add test actions and coverage" * Refactor to add User and App Tables * User Object passing test cases * Update examples * DSPy Todo and documentation updates * Add is_active filtering * Add is_active filtering to the generator * Fix update user metadata * working, but weird compiler error * fixed str error in optimizer * ship * sentry * Open Telemetry * optional logging with environment variables * add actions again? (#29) * add postgres * add openai key * readd coverage * desyncify and add detailed coverage * ⚙️ chore: update start script in VS Code to include poetry install --no-root before running uvicorn (#33) * Refactored code but need to tweak asyncpg * Working Async API using Psycopg3 * Update Workflow Connection URI * Update Workflow Connection URI in coverage test as well * Skeleton for Dialectic API * Fixes DEV-217 URL Encoding * Add Built-in Langchain Utility function * Sphinx Docs MVP * Metadata filtering for all fixes dev-261 * Basic Dialectic Endpoint fixes dev-253 * Working Fact Deriver * 0.0.5 Docs and README updates * Cloudflare Sphinx --------- Co-authored-by: hyusap <paulayush@gmail.com> Co-authored-by: vintro <vince@plasticlabs.ai>
This commit is contained in:
parent
611981f372
commit
995a6d0644
|
|
@ -0,0 +1,47 @@
|
|||
name: Run Coverage
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
test:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install poetry
|
||||
run: |
|
||||
pip install poetry
|
||||
- name: Start Database
|
||||
run: |
|
||||
cd api/local
|
||||
docker compose up --wait
|
||||
cd ../..
|
||||
- name: Start Server
|
||||
run: |
|
||||
cd api
|
||||
poetry install --no-root
|
||||
poetry run uvicorn src.main:app &
|
||||
sleep 5
|
||||
cd ..
|
||||
env:
|
||||
DATABASE_TYPE: postgres
|
||||
CONNECTION_URI: postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
- name: Run Tests
|
||||
run: |
|
||||
cd sdk
|
||||
poetry install
|
||||
poetry run coverage run -m pytest
|
||||
poetry run coverage report --format=markdown > coverage.md
|
||||
cd ..
|
||||
- name: Add Coverage PR Comment
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
recreate: true
|
||||
path: sdk/coverage.md
|
||||
- name: Stop Server
|
||||
run: |
|
||||
kill $(jobs -p) || true
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
name: Run Tests
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install poetry
|
||||
run: |
|
||||
pip install poetry
|
||||
- name: Start Database
|
||||
run: |
|
||||
cd api/local
|
||||
docker compose up --wait
|
||||
cd ../..
|
||||
- name: Start Server
|
||||
run: |
|
||||
cd api
|
||||
poetry install --no-root
|
||||
poetry run uvicorn src.main:app &
|
||||
sleep 5
|
||||
cd ..
|
||||
env:
|
||||
DATABASE_TYPE: postgres
|
||||
CONNECTION_URI: postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
- name: Run Tests
|
||||
run: |
|
||||
cd sdk
|
||||
poetry install
|
||||
poetry run pytest
|
||||
cd ..
|
||||
- name: Stop Database
|
||||
run: |
|
||||
cd api/local
|
||||
docker compose down
|
||||
cd ../..
|
||||
- name: Stop Server
|
||||
run: |
|
||||
kill $(jobs -p) || true
|
||||
|
|
@ -74,7 +74,7 @@ instance/
|
|||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
**/docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
|
|
@ -165,3 +165,5 @@ cython_debug/
|
|||
#.idea/
|
||||
|
||||
.DS_Store
|
||||
|
||||
supabase/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Honcho
|
||||

|
||||

|
||||
[](https://discord.gg/plasticlabs)
|
||||

|
||||

|
||||
|
|
|
|||
|
|
@ -1,7 +1,28 @@
|
|||
DATABASE_TYPE=sqlite
|
||||
CONNECTION_URI=sqlite://
|
||||
|
||||
DATABASE_TYPE=postgres
|
||||
CONNECTION_URI=postgresql://testuser:testpwd@localhost:5432/honcho
|
||||
CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
|
||||
OPENAI_API_KEY=
|
||||
|
||||
# Logging
|
||||
|
||||
OPENTELEMETRY_ENABLED=false # Set to true to enable OpenTelemetry logging and tracing
|
||||
SENTRY_ENABLED=false # Set to true to enable Sentry logging and tracing
|
||||
|
||||
## Sentry
|
||||
SENTRY_DSN=
|
||||
|
||||
## Open Telemetry
|
||||
|
||||
OTEL_SERVICE_NAME=honcho
|
||||
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
|
||||
OTEL_PYTHON_LOG_CORRELATION=true
|
||||
|
||||
OTEL_PYTHON_LOG_LEVEL=
|
||||
OTEL_EXPORTER_OTLP_PROTOCOL=
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT=
|
||||
OTEL_EXPORTER_OTLP_HEADERS=
|
||||
OTEL_RESOURCE_ATTRIBUTES=
|
||||
|
||||
DEBUG_LOG_OTEL_TO_PROVIDER=false
|
||||
DEBUG_LOG_OTEL_TO_CONSOLE=true
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
{
|
||||
"label": "start",
|
||||
"type": "shell",
|
||||
"command": "poetry run uvicorn src.main:app --reload",
|
||||
"command": "poetry install --no-root && poetry run uvicorn src.main:app --reload",
|
||||
"group": "none",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
|
|
@ -12,7 +12,8 @@
|
|||
},
|
||||
"runOptions": {
|
||||
"runOn": "folderOpen"
|
||||
}
|
||||
},
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.0.5] — 2024-03-14
|
||||
|
||||
### Added
|
||||
|
||||
* Metadata to all data primitives (Users, Sessions, Messages, etc.)
|
||||
* Ability to filter paginated GET requests by JSON filter based on metadata
|
||||
* Optional Sentry error monitoring
|
||||
* Optional Opentelemetry logging
|
||||
* Dialectic API to interact with honcho agent and get insights about users
|
||||
* Automatic Fact Derivation Script for automatically generating simple memory
|
||||
|
||||
### Changed
|
||||
|
||||
* API Server now uses async methods to make use of benefits of FastAPI
|
||||
|
||||
|
||||
## [0.0.4] — 2024-02-22
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ kill_timeout = "5s"
|
|||
|
||||
[processes]
|
||||
api = "python -m uvicorn src.main:app --host 0.0.0.0 --port 8000"
|
||||
deriver = "python -m src.harvester"
|
||||
|
||||
[http_service]
|
||||
internal_port = 8000
|
||||
auto_stop_machines = true
|
||||
auto_stop_machines = false
|
||||
auto_start_machines = true
|
||||
min_machines_running = 1
|
||||
processes = ["api"]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,21 +1,32 @@
|
|||
[tool.poetry]
|
||||
name = "honcho"
|
||||
version = "0.0.4"
|
||||
version = "0.0.5"
|
||||
description = "Honcho Server"
|
||||
authors = ["Plastic Labs <hello@plasticlabs.ai>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8"
|
||||
python = "^3.8.1"
|
||||
fastapi = "^0.109.0"
|
||||
uvicorn = "^0.24.0.post1"
|
||||
python-dotenv = "^1.0.0"
|
||||
sqlalchemy = "^2.0.25"
|
||||
psycopg2-binary = "^2.9.9"
|
||||
slowapi = "^0.1.8"
|
||||
fastapi-pagination = "^0.12.14"
|
||||
pgvector = "^0.2.5"
|
||||
openai = "^1.12.0"
|
||||
sentry-sdk = {extras = ["fastapi", "sqlalchemy"], version = "^1.40.5"}
|
||||
opentelemetry-instrumentation-fastapi = "^0.44b0"
|
||||
opentelemetry-api = "^1.23.0"
|
||||
opentelemetry-sdk = "^1.23.0"
|
||||
opentelemetry-exporter-otlp = "^1.23.0"
|
||||
opentelemetry-instrumentation-sqlalchemy = "^0.44b0"
|
||||
opentelemetry-instrumentation-logging = "^0.44b0"
|
||||
greenlet = "^3.0.3"
|
||||
realtime = "^1.0.2"
|
||||
psycopg = {extras = ["binary"], version = "^3.1.18"}
|
||||
langchain = "^0.1.12"
|
||||
langchain-openai = "^0.0.8"
|
||||
|
||||
[tool.ruff.lint]
|
||||
# from https://docs.astral.sh/ruff/linter/#rule-selection example
|
||||
|
|
@ -33,6 +44,8 @@ select = [
|
|||
# isort
|
||||
"I",
|
||||
]
|
||||
[tool.ruff.flake8-bugbear]
|
||||
extend-immutable-calls = ["fastapi.Depends"]
|
||||
|
||||
|
||||
[build-system]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
import os
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from langchain_core.prompts import (
|
||||
ChatPromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
load_prompt,
|
||||
)
|
||||
from langchain_openai import ChatOpenAI
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from . import crud, schemas
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# from supabase import Client
|
||||
|
||||
SYSTEM_DIALECTIC = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/dialectic.yaml")
|
||||
)
|
||||
system_dialectic: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_DIALECTIC
|
||||
)
|
||||
|
||||
llm: ChatOpenAI = ChatOpenAI(model_name="gpt-4")
|
||||
|
||||
|
||||
async def chat(
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
query: str,
|
||||
db: AsyncSession,
|
||||
):
|
||||
collection = await crud.get_collection_by_name(db, app_id, user_id, "honcho")
|
||||
retrieved_facts = None
|
||||
if collection is None:
|
||||
collection_create = schemas.CollectionCreate(name="honcho", metadata={})
|
||||
collection = await crud.create_collection(
|
||||
db,
|
||||
collection=collection_create,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
)
|
||||
else:
|
||||
retrieved_documents = await crud.query_documents(
|
||||
db=db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
collection_id=collection.id,
|
||||
query=query,
|
||||
top_k=1,
|
||||
)
|
||||
if len(retrieved_documents) > 0:
|
||||
retrieved_facts = retrieved_documents[0].content
|
||||
|
||||
dialectic_prompt = ChatPromptTemplate.from_messages([system_dialectic])
|
||||
chain = dialectic_prompt | llm
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"agent_input": query,
|
||||
"retrieved_facts": retrieved_facts if retrieved_facts else "None",
|
||||
}
|
||||
)
|
||||
|
||||
return schemas.AgentChat(content=response.content)
|
||||
|
||||
|
||||
async def hydrate():
|
||||
pass
|
||||
|
||||
|
||||
async def insight():
|
||||
pass
|
||||
354
api/src/crud.py
354
api/src/crud.py
|
|
@ -5,8 +5,9 @@ from typing import Optional, Sequence
|
|||
from openai import OpenAI
|
||||
from sqlalchemy import Select, select
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
# from sqlalchemy.orm import Session
|
||||
from . import models, schemas
|
||||
|
||||
openai_client = OpenAI()
|
||||
|
|
@ -16,32 +17,36 @@ openai_client = OpenAI()
|
|||
########################################################
|
||||
|
||||
|
||||
def get_app(db: Session, app_id: uuid.UUID) -> Optional[models.App]:
|
||||
async def get_app(db: AsyncSession, app_id: uuid.UUID) -> Optional[models.App]:
|
||||
stmt = select(models.App).where(models.App.id == app_id)
|
||||
app = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
app = result.scalar_one_or_none()
|
||||
return app
|
||||
|
||||
|
||||
def get_app_by_name(db: Session, name: str) -> Optional[models.App]:
|
||||
async def get_app_by_name(db: AsyncSession, name: str) -> Optional[models.App]:
|
||||
stmt = select(models.App).where(models.App.name == name)
|
||||
app = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
app = result.scalar_one_or_none()
|
||||
return app
|
||||
|
||||
|
||||
# def get_apps(db: Session) -> Sequence[models.App]:
|
||||
# def get_apps(db: AsyncSession) -> Sequence[models.App]:
|
||||
# return db.query(models.App).all()
|
||||
|
||||
|
||||
def create_app(db: Session, app: schemas.AppCreate) -> models.App:
|
||||
async def create_app(db: AsyncSession, app: schemas.AppCreate) -> models.App:
|
||||
honcho_app = models.App(name=app.name, h_metadata=app.metadata)
|
||||
db.add(honcho_app)
|
||||
db.commit()
|
||||
db.refresh(honcho_app)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_app)
|
||||
return honcho_app
|
||||
|
||||
|
||||
def update_app(db: Session, app_id: uuid.UUID, app: schemas.AppUpdate) -> models.App:
|
||||
honcho_app = get_app(db, app_id)
|
||||
async def update_app(
|
||||
db: AsyncSession, app_id: uuid.UUID, app: schemas.AppUpdate
|
||||
) -> models.App:
|
||||
honcho_app = await get_app(db, app_id)
|
||||
if honcho_app is None:
|
||||
raise ValueError("App not found")
|
||||
if app.name is not None:
|
||||
|
|
@ -49,12 +54,12 @@ def update_app(db: Session, app_id: uuid.UUID, app: schemas.AppUpdate) -> models
|
|||
if app.metadata is not None:
|
||||
honcho_app.h_metadata = app.metadata
|
||||
|
||||
db.commit()
|
||||
db.refresh(honcho_app)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_app)
|
||||
return honcho_app
|
||||
|
||||
|
||||
# def delete_app(db: Session, app_id: uuid.UUID) -> bool:
|
||||
# def delete_app(db: AsyncSession, app_id: uuid.UUID) -> bool:
|
||||
# existing_app = get_app(db, app_id)
|
||||
# if existing_app is None:
|
||||
# return False
|
||||
|
|
@ -68,8 +73,8 @@ def update_app(db: Session, app_id: uuid.UUID, app: schemas.AppUpdate) -> models
|
|||
########################################################
|
||||
|
||||
|
||||
def create_user(
|
||||
db: Session, app_id: uuid.UUID, user: schemas.UserCreate
|
||||
async def create_user(
|
||||
db: AsyncSession, app_id: uuid.UUID, user: schemas.UserCreate
|
||||
) -> models.User:
|
||||
honcho_user = models.User(
|
||||
app_id=app_id,
|
||||
|
|
@ -77,37 +82,48 @@ def create_user(
|
|||
h_metadata=user.metadata,
|
||||
)
|
||||
db.add(honcho_user)
|
||||
db.commit()
|
||||
db.refresh(honcho_user)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_user)
|
||||
return honcho_user
|
||||
|
||||
|
||||
def get_user(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID
|
||||
async def get_user(
|
||||
db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID
|
||||
) -> Optional[models.User]:
|
||||
stmt = (
|
||||
select(models.User)
|
||||
.where(models.User.app_id == app_id)
|
||||
.where(models.User.id == user_id)
|
||||
)
|
||||
user = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
user = result.scalar_one_or_none()
|
||||
return user
|
||||
|
||||
|
||||
def get_user_by_name(
|
||||
db: Session, app_id: uuid.UUID, name: str
|
||||
async def get_user_by_name(
|
||||
db: AsyncSession, app_id: uuid.UUID, name: str
|
||||
) -> Optional[models.User]:
|
||||
stmt = (
|
||||
select(models.User)
|
||||
.where(models.User.app_id == app_id)
|
||||
.where(models.User.name == name)
|
||||
)
|
||||
user = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
user = result.scalar_one_or_none()
|
||||
return user
|
||||
|
||||
|
||||
def get_users(db: Session, app_id: uuid.UUID, reverse: bool = False) -> Select:
|
||||
async def get_users(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
reverse: bool = False,
|
||||
filter: Optional[dict] = None,
|
||||
) -> Select:
|
||||
stmt = select(models.User).where(models.User.app_id == app_id)
|
||||
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.User.h_metadata.contains(filter))
|
||||
|
||||
if reverse:
|
||||
stmt = stmt.order_by(models.User.created_at.desc())
|
||||
else:
|
||||
|
|
@ -116,10 +132,10 @@ def get_users(db: Session, app_id: uuid.UUID, reverse: bool = False) -> Select:
|
|||
return stmt
|
||||
|
||||
|
||||
def update_user(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID, user: schemas.UserUpdate
|
||||
async def update_user(
|
||||
db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID, user: schemas.UserUpdate
|
||||
) -> models.User:
|
||||
honcho_user = get_user(db, app_id, user_id)
|
||||
honcho_user = await get_user(db, app_id, user_id)
|
||||
if honcho_user is None:
|
||||
raise ValueError("User not found")
|
||||
if user.name is not None:
|
||||
|
|
@ -127,12 +143,12 @@ def update_user(
|
|||
if user.metadata is not None:
|
||||
honcho_user.h_metadata = user.metadata
|
||||
|
||||
db.commit()
|
||||
db.refresh(honcho_user)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_user)
|
||||
return honcho_user
|
||||
|
||||
|
||||
# def delete_user(db: Session, app_id: uuid.UUID, user_id: uuid.UUID) -> bool:
|
||||
# def delete_user(db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID) -> bool:
|
||||
# existing_user = get_user(db, app_id, user_id)
|
||||
# if existing_user is None:
|
||||
# return False
|
||||
|
|
@ -145,8 +161,8 @@ def update_user(
|
|||
########################################################
|
||||
|
||||
|
||||
def get_session(
|
||||
db: Session,
|
||||
async def get_session(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
user_id: Optional[uuid.UUID] = None,
|
||||
|
|
@ -159,17 +175,19 @@ def get_session(
|
|||
)
|
||||
if user_id is not None:
|
||||
stmt = stmt.where(models.Session.user_id == user_id)
|
||||
session = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
session = result.scalar_one_or_none()
|
||||
return session
|
||||
|
||||
|
||||
def get_sessions(
|
||||
db: Session,
|
||||
async def get_sessions(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
location_id: Optional[str] = None,
|
||||
reverse: Optional[bool] = False,
|
||||
is_active: Optional[bool] = False,
|
||||
filter: Optional[dict] = None,
|
||||
) -> Select:
|
||||
stmt = (
|
||||
select(models.Session)
|
||||
|
|
@ -181,6 +199,9 @@ def get_sessions(
|
|||
if is_active:
|
||||
stmt = stmt.where(models.Session.is_active.is_(True))
|
||||
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.Session.h_metadata.contains(filter))
|
||||
|
||||
if reverse:
|
||||
stmt = stmt.order_by(models.Session.created_at.desc())
|
||||
else:
|
||||
|
|
@ -192,28 +213,34 @@ def get_sessions(
|
|||
return stmt
|
||||
|
||||
|
||||
def create_session(
|
||||
db: Session, session: schemas.SessionCreate, app_id: uuid.UUID, user_id: uuid.UUID
|
||||
async def create_session(
|
||||
db: AsyncSession,
|
||||
session: schemas.SessionCreate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
) -> models.Session:
|
||||
honcho_user = await get_user(db, app_id=app_id, user_id=user_id)
|
||||
if honcho_user is None:
|
||||
raise ValueError("User not found")
|
||||
honcho_session = models.Session(
|
||||
user_id=user_id,
|
||||
location_id=session.location_id,
|
||||
h_metadata=session.metadata,
|
||||
)
|
||||
db.add(honcho_session)
|
||||
db.commit()
|
||||
db.refresh(honcho_session)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_session)
|
||||
return honcho_session
|
||||
|
||||
|
||||
def update_session(
|
||||
db: Session,
|
||||
async def update_session(
|
||||
db: AsyncSession,
|
||||
session: schemas.SessionUpdate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
) -> bool:
|
||||
honcho_session = get_session(
|
||||
honcho_session = await get_session(
|
||||
db, app_id=app_id, session_id=session_id, user_id=user_id
|
||||
)
|
||||
if honcho_session is None:
|
||||
|
|
@ -222,13 +249,13 @@ def update_session(
|
|||
session.metadata is not None
|
||||
): # Need to explicitly be there won't make it empty by default
|
||||
honcho_session.h_metadata = session.metadata
|
||||
db.commit()
|
||||
db.refresh(honcho_session)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_session)
|
||||
return honcho_session
|
||||
|
||||
|
||||
def delete_session(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID, session_id: uuid.UUID
|
||||
async def delete_session(
|
||||
db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID, session_id: uuid.UUID
|
||||
) -> bool:
|
||||
stmt = (
|
||||
select(models.Session)
|
||||
|
|
@ -237,11 +264,12 @@ def delete_session(
|
|||
.where(models.User.app_id == app_id)
|
||||
.where(models.Session.user_id == user_id)
|
||||
)
|
||||
honcho_session = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
honcho_session = result.scalar_one_or_none()
|
||||
if honcho_session is None:
|
||||
return False
|
||||
honcho_session.is_active = False
|
||||
db.commit()
|
||||
await db.commit()
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -250,8 +278,8 @@ def delete_session(
|
|||
########################################################
|
||||
|
||||
|
||||
def create_message(
|
||||
db: Session,
|
||||
async def create_message(
|
||||
db: AsyncSession,
|
||||
message: schemas.MessageCreate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
|
|
@ -267,19 +295,21 @@ def create_message(
|
|||
session_id=session_id,
|
||||
is_user=message.is_user,
|
||||
content=message.content,
|
||||
h_metadata=message.metadata,
|
||||
)
|
||||
db.add(honcho_message)
|
||||
db.commit()
|
||||
db.refresh(honcho_message)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_message)
|
||||
return honcho_message
|
||||
|
||||
|
||||
def get_messages(
|
||||
db: Session,
|
||||
async def get_messages(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
reverse: Optional[bool] = False,
|
||||
filter: Optional[dict] = None,
|
||||
) -> Select:
|
||||
stmt = (
|
||||
select(models.Message)
|
||||
|
|
@ -291,6 +321,9 @@ def get_messages(
|
|||
.where(models.Message.session_id == session_id)
|
||||
)
|
||||
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.Message.h_metadata.contains(filter))
|
||||
|
||||
if reverse:
|
||||
stmt = stmt.order_by(models.Message.created_at.desc())
|
||||
else:
|
||||
|
|
@ -299,8 +332,8 @@ def get_messages(
|
|||
return stmt
|
||||
|
||||
|
||||
def get_message(
|
||||
db: Session,
|
||||
async def get_message(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
|
|
@ -316,7 +349,30 @@ def get_message(
|
|||
.where(models.Message.session_id == session_id)
|
||||
.where(models.Message.id == message_id)
|
||||
)
|
||||
return db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def update_message(
|
||||
db: AsyncSession,
|
||||
message: schemas.MessageUpdate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
message_id: uuid.UUID,
|
||||
) -> bool:
|
||||
honcho_message = await get_message(
|
||||
db, app_id=app_id, session_id=session_id, user_id=user_id, message_id=message_id
|
||||
)
|
||||
if honcho_message is None:
|
||||
raise ValueError("Message not found or does not belong to user")
|
||||
if (
|
||||
message.metadata is not None
|
||||
): # Need to explicitly be there won't make it empty by default
|
||||
honcho_message.h_metadata = message.metadata
|
||||
await db.commit()
|
||||
await db.refresh(honcho_message)
|
||||
return honcho_message
|
||||
|
||||
|
||||
########################################################
|
||||
|
|
@ -324,8 +380,8 @@ def get_message(
|
|||
########################################################
|
||||
|
||||
|
||||
def create_metamessage(
|
||||
db: Session,
|
||||
async def create_metamessage(
|
||||
db: AsyncSession,
|
||||
metamessage: schemas.MetamessageCreate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
|
|
@ -345,21 +401,23 @@ def create_metamessage(
|
|||
message_id=metamessage.message_id,
|
||||
metamessage_type=metamessage.metamessage_type,
|
||||
content=metamessage.content,
|
||||
h_metadata=metamessage.metadata,
|
||||
)
|
||||
|
||||
db.add(honcho_metamessage)
|
||||
db.commit()
|
||||
db.refresh(honcho_metamessage)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_metamessage)
|
||||
return honcho_metamessage
|
||||
|
||||
|
||||
def get_metamessages(
|
||||
db: Session,
|
||||
async def get_metamessages(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
message_id: Optional[uuid.UUID],
|
||||
metamessage_type: Optional[str] = None,
|
||||
filter: Optional[dict] = None,
|
||||
reverse: Optional[bool] = False,
|
||||
) -> Select:
|
||||
stmt = (
|
||||
|
|
@ -379,6 +437,9 @@ def get_metamessages(
|
|||
if metamessage_type is not None:
|
||||
stmt = stmt.where(models.Metamessage.metamessage_type == metamessage_type)
|
||||
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.Metamessage.h_metadata.contains(filter))
|
||||
|
||||
if reverse:
|
||||
stmt = stmt.order_by(models.Metamessage.created_at.desc())
|
||||
else:
|
||||
|
|
@ -387,8 +448,8 @@ def get_metamessages(
|
|||
return stmt
|
||||
|
||||
|
||||
def get_metamessage(
|
||||
db: Session,
|
||||
async def get_metamessage(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
|
|
@ -407,7 +468,37 @@ def get_metamessage(
|
|||
.where(models.Metamessage.message_id == message_id)
|
||||
.where(models.Metamessage.id == metamessage_id)
|
||||
)
|
||||
return db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def update_metamessage(
|
||||
db: AsyncSession,
|
||||
metamessage: schemas.MetamessageUpdate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
metamessage_id: uuid.UUID,
|
||||
) -> bool:
|
||||
honcho_metamessage = await get_metamessage(
|
||||
db,
|
||||
app_id=app_id,
|
||||
session_id=session_id,
|
||||
user_id=user_id,
|
||||
message_id=metamessage.message_id,
|
||||
metamessage_id=metamessage_id,
|
||||
)
|
||||
if honcho_metamessage is None:
|
||||
raise ValueError("Metamessage not found or does not belong to user")
|
||||
if (
|
||||
metamessage.metadata is not None
|
||||
): # Need to explicitly be there won't make it empty by default
|
||||
honcho_metamessage.h_metadata = metamessage.metadata
|
||||
if metamessage.metamessage_type is not None:
|
||||
honcho_metamessage.metamessage_type = metamessage.metamessage_type
|
||||
await db.commit()
|
||||
await db.refresh(honcho_metamessage)
|
||||
return honcho_metamessage
|
||||
|
||||
|
||||
########################################################
|
||||
|
|
@ -417,8 +508,12 @@ def get_metamessage(
|
|||
# Should be very similar to the session methods
|
||||
|
||||
|
||||
def get_collections(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID, reverse: Optional[bool] = False
|
||||
async def get_collections(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
reverse: Optional[bool] = False,
|
||||
filter: Optional[dict] = None,
|
||||
) -> Select:
|
||||
"""Get a distinct list of the names of collections associated with a user"""
|
||||
stmt = (
|
||||
|
|
@ -428,6 +523,9 @@ def get_collections(
|
|||
.where(models.User.id == user_id)
|
||||
)
|
||||
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.Collection.h_metadata.contains(filter))
|
||||
|
||||
if reverse:
|
||||
stmt = stmt.order_by(models.Collection.created_at.desc())
|
||||
else:
|
||||
|
|
@ -436,8 +534,8 @@ def get_collections(
|
|||
return stmt
|
||||
|
||||
|
||||
def get_collection_by_id(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID, collection_id: uuid.UUID
|
||||
async def get_collection_by_id(
|
||||
db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID, collection_id: uuid.UUID
|
||||
) -> Optional[models.Collection]:
|
||||
stmt = (
|
||||
select(models.Collection)
|
||||
|
|
@ -446,12 +544,13 @@ def get_collection_by_id(
|
|||
.where(models.User.id == user_id)
|
||||
.where(models.Collection.id == collection_id)
|
||||
)
|
||||
collection = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
collection = result.scalar_one_or_none()
|
||||
return collection
|
||||
|
||||
|
||||
def get_collection_by_name(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID, name: str
|
||||
async def get_collection_by_name(
|
||||
db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID, name: str
|
||||
) -> Optional[models.Collection]:
|
||||
stmt = (
|
||||
select(models.Collection)
|
||||
|
|
@ -460,12 +559,13 @@ def get_collection_by_name(
|
|||
.where(models.User.id == user_id)
|
||||
.where(models.Collection.name == name)
|
||||
)
|
||||
collection = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
collection = result.scalar_one_or_none()
|
||||
return collection
|
||||
|
||||
|
||||
def create_collection(
|
||||
db: Session,
|
||||
async def create_collection(
|
||||
db: AsyncSession,
|
||||
collection: schemas.CollectionCreate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
|
|
@ -473,41 +573,44 @@ def create_collection(
|
|||
honcho_collection = models.Collection(
|
||||
user_id=user_id,
|
||||
name=collection.name,
|
||||
h_metadata=collection.metadata,
|
||||
)
|
||||
try:
|
||||
db.add(honcho_collection)
|
||||
db.commit()
|
||||
await db.commit()
|
||||
except IntegrityError:
|
||||
db.rollback()
|
||||
raise ValueError("Collection already exists")
|
||||
db.refresh(honcho_collection)
|
||||
await db.rollback()
|
||||
raise ValueError("Collection already exists") from None
|
||||
await db.refresh(honcho_collection)
|
||||
return honcho_collection
|
||||
|
||||
|
||||
def update_collection(
|
||||
db: Session,
|
||||
async def update_collection(
|
||||
db: AsyncSession,
|
||||
collection: schemas.CollectionUpdate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
) -> models.Collection:
|
||||
honcho_collection = get_collection_by_id(
|
||||
honcho_collection = await get_collection_by_id(
|
||||
db, app_id=app_id, user_id=user_id, collection_id=collection_id
|
||||
)
|
||||
if honcho_collection is None:
|
||||
raise ValueError("collection not found or does not belong to user")
|
||||
if collection.metadata is not None:
|
||||
honcho_collection.h_metadata = collection.metadata
|
||||
try:
|
||||
honcho_collection.name = collection.name
|
||||
db.commit()
|
||||
await db.commit()
|
||||
except IntegrityError:
|
||||
db.rollback()
|
||||
raise ValueError("Collection already exists")
|
||||
db.refresh(honcho_collection)
|
||||
await db.rollback()
|
||||
raise ValueError("Collection already exists") from None
|
||||
await db.refresh(honcho_collection)
|
||||
return honcho_collection
|
||||
|
||||
|
||||
def delete_collection(
|
||||
db: Session, app_id: uuid.UUID, user_id: uuid.UUID, collection_id: uuid.UUID
|
||||
async def delete_collection(
|
||||
db: AsyncSession, app_id: uuid.UUID, user_id: uuid.UUID, collection_id: uuid.UUID
|
||||
) -> bool:
|
||||
"""
|
||||
Delete a Collection and all documents associated with it. Takes advantage of
|
||||
|
|
@ -520,11 +623,12 @@ def delete_collection(
|
|||
.where(models.User.id == user_id)
|
||||
.where(models.Collection.id == collection_id)
|
||||
)
|
||||
honcho_collection = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
honcho_collection = result.scalar_one_or_none()
|
||||
if honcho_collection is None:
|
||||
return False
|
||||
db.delete(honcho_collection)
|
||||
db.commit()
|
||||
await db.delete(honcho_collection)
|
||||
await db.commit()
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -535,12 +639,13 @@ def delete_collection(
|
|||
# Should be similar to the messages methods outside of query
|
||||
|
||||
|
||||
def get_documents(
|
||||
db: Session,
|
||||
async def get_documents(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
reverse: Optional[bool] = False,
|
||||
filter: Optional[dict] = None,
|
||||
) -> Select:
|
||||
stmt = (
|
||||
select(models.Document)
|
||||
|
|
@ -551,6 +656,9 @@ def get_documents(
|
|||
.where(models.Document.collection_id == collection_id)
|
||||
)
|
||||
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.Document.h_metadata.contains(filter))
|
||||
|
||||
if reverse:
|
||||
stmt = stmt.order_by(models.Document.created_at.desc())
|
||||
else:
|
||||
|
|
@ -559,8 +667,8 @@ def get_documents(
|
|||
return stmt
|
||||
|
||||
|
||||
def get_document(
|
||||
db: Session,
|
||||
async def get_document(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
|
|
@ -576,16 +684,18 @@ def get_document(
|
|||
.where(models.Document.id == document_id)
|
||||
)
|
||||
|
||||
document = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
document = result.scalar_one_or_none()
|
||||
return document
|
||||
|
||||
|
||||
def query_documents(
|
||||
db: Session,
|
||||
async def query_documents(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
query: str,
|
||||
filter: Optional[dict] = None,
|
||||
top_k: int = 5,
|
||||
) -> Sequence[models.Document]:
|
||||
response = openai_client.embeddings.create(
|
||||
|
|
@ -599,23 +709,26 @@ def query_documents(
|
|||
.where(models.User.app_id == app_id)
|
||||
.where(models.User.id == user_id)
|
||||
.where(models.Document.collection_id == collection_id)
|
||||
.order_by(models.Document.embedding.cosine_distance(embedding_query))
|
||||
.limit(top_k)
|
||||
# .limit(top_k)
|
||||
)
|
||||
# if metadata is not None:
|
||||
# stmt = stmt.where(models.Document.h_metadata.contains(metadata))
|
||||
return db.scalars(stmt).all()
|
||||
if filter is not None:
|
||||
stmt = stmt.where(models.Document.h_metadata.contains(filter))
|
||||
stmt = stmt.limit(top_k).order_by(
|
||||
models.Document.embedding.cosine_distance(embedding_query)
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
def create_document(
|
||||
db: Session,
|
||||
async def create_document(
|
||||
db: AsyncSession,
|
||||
document: schemas.DocumentCreate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
) -> models.Document:
|
||||
"""Embed a message as a vector and create a document"""
|
||||
collection = get_collection_by_id(
|
||||
collection = await get_collection_by_id(
|
||||
db, app_id=app_id, collection_id=collection_id, user_id=user_id
|
||||
)
|
||||
if collection is None:
|
||||
|
|
@ -634,20 +747,20 @@ def create_document(
|
|||
embedding=embedding,
|
||||
)
|
||||
db.add(honcho_document)
|
||||
db.commit()
|
||||
db.refresh(honcho_document)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_document)
|
||||
return honcho_document
|
||||
|
||||
|
||||
def update_document(
|
||||
db: Session,
|
||||
async def update_document(
|
||||
db: AsyncSession,
|
||||
document: schemas.DocumentUpdate,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
document_id: uuid.UUID,
|
||||
) -> bool:
|
||||
honcho_document = get_document(
|
||||
honcho_document = await get_document(
|
||||
db,
|
||||
app_id=app_id,
|
||||
collection_id=collection_id,
|
||||
|
|
@ -667,13 +780,13 @@ def update_document(
|
|||
|
||||
if document.metadata is not None:
|
||||
honcho_document.h_metadata = document.metadata
|
||||
db.commit()
|
||||
db.refresh(honcho_document)
|
||||
await db.commit()
|
||||
await db.refresh(honcho_document)
|
||||
return honcho_document
|
||||
|
||||
|
||||
def delete_document(
|
||||
db: Session,
|
||||
async def delete_document(
|
||||
db: AsyncSession,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
|
|
@ -688,9 +801,10 @@ def delete_document(
|
|||
.where(models.Document.collection_id == collection_id)
|
||||
.where(models.Document.id == document_id)
|
||||
)
|
||||
document = db.scalars(stmt).one_or_none()
|
||||
result = await db.execute(stmt)
|
||||
document = result.scalar_one_or_none()
|
||||
if document is None:
|
||||
return False
|
||||
db.delete(document)
|
||||
db.commit()
|
||||
await db.delete(document)
|
||||
await db.commit()
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -1,20 +1,31 @@
|
|||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
connect_args = {}
|
||||
|
||||
if os.environ["DATABASE_TYPE"] == "sqlite": # https://fastapi.tiangolo.com/tutorial/sql-databases/#note
|
||||
if (
|
||||
os.environ["DATABASE_TYPE"] == "sqlite"
|
||||
): # https://fastapi.tiangolo.com/tutorial/sql-databases/#note
|
||||
connect_args = {"check_same_thread": False}
|
||||
|
||||
engine = create_engine(
|
||||
engine = create_async_engine(
|
||||
os.environ["CONNECTION_URI"], connect_args=connect_args, echo=True
|
||||
)
|
||||
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
SessionLocal = async_sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
def scaffold_db():
|
||||
"""Use a Sync Engine for scaffolding the database. DDL operations are unavailable
|
||||
with Async Engines
|
||||
"""
|
||||
engine = create_engine(os.environ["CONNECTION_URI"], echo=True)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
engine.dispose()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,203 @@
|
|||
import asyncio
|
||||
import os
|
||||
import uuid
|
||||
from typing import List
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from langchain_core.output_parsers import NumberedListOutputParser
|
||||
from langchain_core.prompts import (
|
||||
ChatPromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
load_prompt,
|
||||
)
|
||||
from langchain_openai import ChatOpenAI
|
||||
from realtime.connection import Socket
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from . import crud, models, schemas
|
||||
from .db import SessionLocal
|
||||
|
||||
load_dotenv()
|
||||
|
||||
SUPABASE_ID = os.getenv("SUPABASE_ID")
|
||||
SUPABASE_API_KEY = os.getenv("SUPABASE_API_KEY")
|
||||
|
||||
llm = ChatOpenAI(model_name="gpt-4")
|
||||
output_parser = NumberedListOutputParser()
|
||||
|
||||
SYSTEM_DERIVE_FACTS = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/derive_facts.yaml")
|
||||
)
|
||||
SYSTEM_CHECK_DUPS = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/check_dup_facts.yaml")
|
||||
)
|
||||
|
||||
system_check_dups: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_CHECK_DUPS
|
||||
)
|
||||
|
||||
system_derive_facts: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_DERIVE_FACTS
|
||||
)
|
||||
|
||||
|
||||
async def callback(payload):
|
||||
# print(payload["record"]["is_user"])
|
||||
# print(type(payload["record"]["is_user"]))
|
||||
if payload["record"]["is_user"]: # Check if the message is from a user
|
||||
session_id = payload["record"]["session_id"]
|
||||
message_id = payload["record"]["id"]
|
||||
content = payload["record"]["content"]
|
||||
|
||||
# Example of querying for a user_id based on session_id, adjust according to your schema
|
||||
session: models.Session
|
||||
user_id: uuid.UUID
|
||||
app_id: uuid.UUID
|
||||
async with SessionLocal() as db:
|
||||
stmt = (
|
||||
select(models.Session)
|
||||
.join(models.Session.messages)
|
||||
.where(models.Message.id == message_id)
|
||||
.where(models.Session.id == session_id)
|
||||
.options(selectinload(models.Session.user))
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
session = result.scalars().one()
|
||||
user = session.user
|
||||
user_id = user.id
|
||||
app_id = user.app_id
|
||||
collection: models.Collection
|
||||
async with SessionLocal() as db:
|
||||
collection = await crud.get_collection_by_name(
|
||||
db, app_id, user_id, "honcho"
|
||||
)
|
||||
if collection is None:
|
||||
collection_create = schemas.CollectionCreate(name="honcho", metadata={})
|
||||
collection = await crud.create_collection(
|
||||
db,
|
||||
collection=collection_create,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
)
|
||||
collection_id = collection.id
|
||||
await process_user_message(
|
||||
content, app_id, user_id, session_id, collection_id, message_id
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
async def process_user_message(
|
||||
content: str,
|
||||
app_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
session_id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
message_id: uuid.UUID,
|
||||
):
|
||||
# TODO get messages for the session
|
||||
async with SessionLocal() as db:
|
||||
messages_stmt = await crud.get_messages(
|
||||
db=db, app_id=app_id, user_id=user_id, session_id=session_id, reverse=True
|
||||
)
|
||||
messages_stmt = messages_stmt.limit(10)
|
||||
response = await db.execute(messages_stmt)
|
||||
messages = response.scalars().all()
|
||||
messages = messages[::-1]
|
||||
contents = [m.content for m in messages]
|
||||
# print(contents)
|
||||
|
||||
facts = await derive_facts(messages, content)
|
||||
print("===================")
|
||||
print(f"DERIVED FACTS: {facts}")
|
||||
print("===================")
|
||||
new_facts = await check_dups(app_id, user_id, collection_id, facts)
|
||||
|
||||
print("===================")
|
||||
print(f"CHECKED FOR DUPLICATES: {new_facts}")
|
||||
print("===================")
|
||||
|
||||
for fact in new_facts:
|
||||
create_document = schemas.DocumentCreate(content=fact)
|
||||
async with SessionLocal() as db:
|
||||
doc = await crud.create_document(
|
||||
db,
|
||||
document=create_document,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
collection_id=collection_id,
|
||||
)
|
||||
print(f"Returned Document: {doc}")
|
||||
# doc = crud.create_document(content=fact)
|
||||
# for fact in new_facts:
|
||||
# session.create_metamessage(
|
||||
# message=user_message, metamessage_type="fact", content=fact
|
||||
# )
|
||||
# print(f"Created fact: {fact}")
|
||||
|
||||
|
||||
async def derive_facts(chat_history, input: str) -> List[str]:
|
||||
"""Derive facts from the user input"""
|
||||
|
||||
fact_derivation = ChatPromptTemplate.from_messages([system_derive_facts])
|
||||
chain = fact_derivation | llm
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"chat_history": [
|
||||
(
|
||||
"user: " + message.content
|
||||
if message.is_user
|
||||
else "ai: " + message.content
|
||||
)
|
||||
for message in chat_history
|
||||
],
|
||||
"user_input": input,
|
||||
}
|
||||
)
|
||||
facts = output_parser.parse(response.content)
|
||||
|
||||
return facts
|
||||
|
||||
|
||||
async def check_dups(
|
||||
app_id: uuid.UUID, user_id: uuid.UUID, collection_id: uuid.UUID, facts: List[str]
|
||||
):
|
||||
"""Check that we're not storing duplicate facts"""
|
||||
|
||||
check_duplication = ChatPromptTemplate.from_messages([system_check_dups])
|
||||
query = " ".join(facts)
|
||||
result = None
|
||||
async with SessionLocal() as db:
|
||||
result = await crud.query_documents(
|
||||
db=db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
collection_id=collection_id,
|
||||
query=query,
|
||||
top_k=10,
|
||||
)
|
||||
# result = collection.query(query=query, top_k=10)
|
||||
existing_facts = [document.content for document in result]
|
||||
print("===================")
|
||||
print(f"Existing Facts {existing_facts}")
|
||||
print("===================")
|
||||
if len(existing_facts) == 0:
|
||||
return facts
|
||||
chain = check_duplication | llm
|
||||
response = await chain.ainvoke({"existing_facts": existing_facts, "facts": facts})
|
||||
new_facts = output_parser.parse(response.content)
|
||||
print("===================")
|
||||
print(f"New Facts {facts}")
|
||||
print("===================")
|
||||
return new_facts
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
URL = f"wss://{SUPABASE_ID}.supabase.co/realtime/v1/websocket?apikey={SUPABASE_API_KEY}&vsn=1.0.0"
|
||||
# URL = f"ws://127.0.0.1:54321/realtime/v1/websocket?apikey={SUPABASE_API_KEY}" # For local Supabase
|
||||
s = Socket(URL)
|
||||
s.connect()
|
||||
|
||||
channel = s.set_channel("realtime:public:messages")
|
||||
channel.join().on("INSERT", lambda payload: asyncio.create_task(callback(payload)))
|
||||
s.listen()
|
||||
648
api/src/main.py
648
api/src/main.py
File diff suppressed because it is too large
Load Diff
|
|
@ -87,6 +87,7 @@ class Message(Base):
|
|||
session_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("sessions.id"), index=True)
|
||||
is_user: Mapped[bool]
|
||||
content: Mapped[str] = mapped_column(String(65535))
|
||||
h_metadata: Mapped[dict] = mapped_column("metadata", ColumnType, default={})
|
||||
|
||||
created_at: Mapped[datetime.datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=datetime.datetime.utcnow
|
||||
|
|
@ -111,6 +112,7 @@ class Metamessage(Base):
|
|||
created_at: Mapped[datetime.datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=datetime.datetime.utcnow
|
||||
)
|
||||
h_metadata: Mapped[dict] = mapped_column("metadata", ColumnType, default={})
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Metamessages(id={self.id}, message_id={self.message_id}, metamessage_type={self.metamessage_type}, content={self.content[10:]})"
|
||||
|
|
@ -125,6 +127,7 @@ class Collection(Base):
|
|||
created_at: Mapped[datetime.datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=datetime.datetime.utcnow
|
||||
)
|
||||
h_metadata: Mapped[dict] = mapped_column("metadata", ColumnType, default={})
|
||||
documents = relationship(
|
||||
"Document", back_populates="collection", cascade="all, delete, delete-orphan"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
_type: prompt
|
||||
input_variables:
|
||||
["existing_facts", "facts"]
|
||||
template: >
|
||||
Your job is to compare the following two lists and keep only unique items:
|
||||
|
||||
Old: ```{existing_facts}```
|
||||
|
||||
New: ```{facts}```
|
||||
|
||||
Remove redundant information from the new list and output the remaining facts as a numbered list. If there's nothing to remove (i.e. the statements are sufficiently different), print "None".
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
_type: prompt
|
||||
input_variables:
|
||||
["chat_history", "user_input"]
|
||||
template: >
|
||||
You are tasked with deriving discrete facts about the user based on their input. The goal is to only extract absolute facts from the message, do not make inferences beyond the text provided.
|
||||
|
||||
chat history: ```{chat_history}```
|
||||
user input: ```{user_input}```
|
||||
|
||||
Output the facts as a numbered list.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
_type: prompt
|
||||
input_variables:
|
||||
["agent_input", "retrieved_facts"]
|
||||
template: >
|
||||
You are tasked with responding to the query based on the context provided.
|
||||
---
|
||||
query: {agent_input}
|
||||
context: {retrieved_facts}
|
||||
---
|
||||
Provide a brief, matter-of-fact, and appropriate response to the query based on the context provided. If the context provided doesn't aid in addressing the query, return None.
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
from pydantic import BaseModel, validator
|
||||
import datetime
|
||||
import uuid
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
|
||||
class AppBase(BaseModel):
|
||||
pass
|
||||
|
|
@ -68,21 +69,37 @@ class User(UserBase):
|
|||
|
||||
|
||||
class MessageBase(BaseModel):
|
||||
content: str
|
||||
is_user: bool
|
||||
|
||||
|
||||
class MessageCreate(MessageBase):
|
||||
pass
|
||||
|
||||
|
||||
class MessageCreate(MessageBase):
|
||||
content: str
|
||||
is_user: bool
|
||||
metadata: dict | None = {}
|
||||
|
||||
|
||||
class MessageUpdate(MessageBase):
|
||||
metadata: dict | None = None
|
||||
|
||||
|
||||
class Message(MessageBase):
|
||||
content: str
|
||||
is_user: bool
|
||||
session_id: uuid.UUID
|
||||
id: uuid.UUID
|
||||
h_metadata: dict
|
||||
metadata: dict
|
||||
created_at: datetime.datetime
|
||||
|
||||
@validator("metadata", pre=True, allow_reuse=True)
|
||||
def fetch_h_metadata(cls, value, values):
|
||||
if "h_metadata" in values:
|
||||
return values["h_metadata"]
|
||||
return {}
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
schema_extra = {"exclude": ["h_metadata"]}
|
||||
|
||||
|
||||
class SessionBase(BaseModel):
|
||||
|
|
@ -120,21 +137,40 @@ class Session(SessionBase):
|
|||
|
||||
|
||||
class MetamessageBase(BaseModel):
|
||||
metamessage_type: str
|
||||
content: str
|
||||
pass
|
||||
|
||||
|
||||
class MetamessageCreate(MetamessageBase):
|
||||
metamessage_type: str
|
||||
content: str
|
||||
message_id: uuid.UUID
|
||||
metadata: dict | None = {}
|
||||
|
||||
|
||||
class MetamessageUpdate(MetamessageBase):
|
||||
message_id: uuid.UUID
|
||||
metamessage_type: str | None = None
|
||||
metadata: dict | None = None
|
||||
|
||||
|
||||
class Metamessage(MetamessageBase):
|
||||
metamessage_type: str
|
||||
content: str
|
||||
id: uuid.UUID
|
||||
message_id: uuid.UUID
|
||||
h_metadata: dict
|
||||
metadata: dict
|
||||
created_at: datetime.datetime
|
||||
|
||||
@validator("metadata", pre=True, allow_reuse=True)
|
||||
def fetch_h_metadata(cls, value, values):
|
||||
if "h_metadata" in values:
|
||||
return values["h_metadata"]
|
||||
return {}
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
schema_extra = {"exclude": ["h_metadata"]}
|
||||
|
||||
|
||||
class CollectionBase(BaseModel):
|
||||
|
|
@ -143,20 +179,31 @@ class CollectionBase(BaseModel):
|
|||
|
||||
class CollectionCreate(CollectionBase):
|
||||
name: str
|
||||
metadata: dict | None = {}
|
||||
|
||||
|
||||
class CollectionUpdate(CollectionBase):
|
||||
name: str
|
||||
metadata: dict | None = None
|
||||
|
||||
|
||||
class Collection(CollectionBase):
|
||||
id: uuid.UUID
|
||||
name: str
|
||||
user_id: uuid.UUID
|
||||
h_metadata: dict
|
||||
metadata: dict
|
||||
created_at: datetime.datetime
|
||||
|
||||
@validator("metadata", pre=True, allow_reuse=True)
|
||||
def fetch_h_metadata(cls, value, values):
|
||||
if "h_metadata" in values:
|
||||
return values["h_metadata"]
|
||||
return {}
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
schema_extra = {"exclude": ["h_metadata"]}
|
||||
|
||||
|
||||
class DocumentBase(BaseModel):
|
||||
|
|
@ -189,3 +236,7 @@ class Document(DocumentBase):
|
|||
class Config:
|
||||
from_attributes = True
|
||||
schema_extra = {"exclude": ["h_metadata"]}
|
||||
|
||||
|
||||
class AgentChat(BaseModel):
|
||||
content: str
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@ from typing import List
|
|||
from uuid import uuid4
|
||||
|
||||
from langchain.prompts import ChatPromptTemplate
|
||||
|
||||
from langchain.schema import AIMessage, HumanMessage, SystemMessage
|
||||
from langchain_community.chat_models.fake import FakeListChatModel
|
||||
|
||||
from honcho import Honcho
|
||||
from honcho.ext.langchain import langchain_message_converter
|
||||
|
||||
app_name = str(uuid4())
|
||||
|
||||
# honcho = Honcho(app_id=app_id, base_url="http://localhost:8000") # uncomment to use local
|
||||
honcho = Honcho(app_name=app_name) # uses demo server at https://demo.honcho.dev
|
||||
honcho = Honcho(
|
||||
app_name=app_name, base_url="http://localhost:8000"
|
||||
) # uncomment to use local
|
||||
# honcho = Honcho(app_name=app_name) # uses demo server at https://demo.honcho.dev
|
||||
honcho.initialize()
|
||||
|
||||
responses = ["Fake LLM Response :)"]
|
||||
|
|
@ -24,14 +28,14 @@ user = honcho.create_user(user_name)
|
|||
session = user.create_session()
|
||||
|
||||
|
||||
def langchain_message_converter(messages: List):
|
||||
new_messages = []
|
||||
for message in messages:
|
||||
if message.is_user:
|
||||
new_messages.append(HumanMessage(content=message.content))
|
||||
else:
|
||||
new_messages.append(AIMessage(content=message.content))
|
||||
return new_messages
|
||||
# def langchain_message_converter(messages: List):
|
||||
# new_messages = []
|
||||
# for message in messages:
|
||||
# if message.is_user:
|
||||
# new_messages.append(HumanMessage(content=message.content))
|
||||
# else:
|
||||
# new_messages.append(AIMessage(content=message.content))
|
||||
# return new_messages
|
||||
|
||||
|
||||
def chat():
|
||||
|
|
|
|||
|
|
@ -125,14 +125,14 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.2.0"
|
||||
version = "4.3.0"
|
||||
description = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
category = "dev"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"},
|
||||
{file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"},
|
||||
{file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"},
|
||||
{file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -166,21 +166,21 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p
|
|||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2023.11.17"
|
||||
version = "2024.2.2"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"},
|
||||
{file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
|
||||
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
|
||||
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.3.2"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
|
|
@ -278,14 +278,14 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "dataclasses-json"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
description = "Easily serialize dataclasses to and from JSON."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
files = [
|
||||
{file = "dataclasses_json-0.6.3-py3-none-any.whl", hash = "sha256:4aeb343357997396f6bca1acae64e486c3a723d8f5c76301888abeccf0c45176"},
|
||||
{file = "dataclasses_json-0.6.3.tar.gz", hash = "sha256:35cb40aae824736fdf959801356641836365219cfe14caeb115c39136f775d2a"},
|
||||
{file = "dataclasses_json-0.6.4-py3-none-any.whl", hash = "sha256:f90578b8a3177f7552f4e1a6e535e84293cd5da421fcce0642d49c0d7bdf8df2"},
|
||||
{file = "dataclasses_json-0.6.4.tar.gz", hash = "sha256:73696ebf24936560cca79a2430cbc4f3dd23ac7bf46ed17f38e5e5e7657a6377"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -451,23 +451,82 @@ files = [
|
|||
docs = ["Sphinx", "furo"]
|
||||
test = ["objgraph", "psutil"]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.14.0"
|
||||
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
|
||||
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "honcho-ai"
|
||||
version = "0.0.1"
|
||||
version = "0.0.4"
|
||||
description = "Python Client SDK for Honcho"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "^3.10"
|
||||
python-versions = "^3.9"
|
||||
files = []
|
||||
develop = true
|
||||
|
||||
[package.dependencies]
|
||||
requests = "^2.31.0"
|
||||
httpx = "^0.26.0"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "../../sdk"
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.4"
|
||||
description = "A minimal low-level HTTP client."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"},
|
||||
{file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = "*"
|
||||
h11 = ">=0.13,<0.15"
|
||||
|
||||
[package.extras]
|
||||
asyncio = ["anyio (>=4.0,<5.0)"]
|
||||
http2 = ["h2 (>=3,<5)"]
|
||||
socks = ["socksio (>=1.0.0,<2.0.0)"]
|
||||
trio = ["trio (>=0.22.0,<0.25.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.26.0"
|
||||
description = "The next generation HTTP client."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"},
|
||||
{file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
anyio = "*"
|
||||
certifi = "*"
|
||||
httpcore = ">=1.0.0,<2.0.0"
|
||||
idna = "*"
|
||||
sniffio = "*"
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli", "brotlicffi"]
|
||||
cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"]
|
||||
http2 = ["h2 (>=3,<5)"]
|
||||
socks = ["socksio (>=1.0.0,<2.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
|
|
@ -509,23 +568,24 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "langchain"
|
||||
version = "0.1.4"
|
||||
version = "0.1.11"
|
||||
description = "Building applications with LLMs through composability"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langchain-0.1.4-py3-none-any.whl", hash = "sha256:6befdd6221f5f326092e31a3c19efdc7ce3d7d1f2e2cab065141071451730ed7"},
|
||||
{file = "langchain-0.1.4.tar.gz", hash = "sha256:8767a9461e2b717ce9a35b1fa20659de89ea86ba9c2a4ff516e05d47ab2d195d"},
|
||||
{file = "langchain-0.1.11-py3-none-any.whl", hash = "sha256:b5e678ac50d85370b9bc28f2c97ad5f029aac1c0cca79cac9354adf72741bc6e"},
|
||||
{file = "langchain-0.1.11.tar.gz", hash = "sha256:03f08cae7cd3f341c54f1042b3fe24d88f39eba7b7eda942735d8ced13fe6da9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = ">=3.8.3,<4.0.0"
|
||||
dataclasses-json = ">=0.5.7,<0.7"
|
||||
jsonpatch = ">=1.33,<2.0"
|
||||
langchain-community = ">=0.0.14,<0.1"
|
||||
langchain-core = ">=0.1.16,<0.2"
|
||||
langsmith = ">=0.0.83,<0.1"
|
||||
langchain-community = ">=0.0.25,<0.1"
|
||||
langchain-core = ">=0.1.29,<0.2"
|
||||
langchain-text-splitters = ">=0.0.1,<0.1"
|
||||
langsmith = ">=0.1.17,<0.2.0"
|
||||
numpy = ">=1,<2"
|
||||
pydantic = ">=1,<3"
|
||||
PyYAML = ">=5.3"
|
||||
|
|
@ -534,13 +594,13 @@ SQLAlchemy = ">=1.4,<3"
|
|||
tenacity = ">=8.1.0,<9.0.0"
|
||||
|
||||
[package.extras]
|
||||
azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"]
|
||||
azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"]
|
||||
clarifai = ["clarifai (>=9.1.0)"]
|
||||
cli = ["typer (>=0.9.0,<0.10.0)"]
|
||||
cohere = ["cohere (>=4,<5)"]
|
||||
docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"]
|
||||
embeddings = ["sentence-transformers (>=2,<3)"]
|
||||
extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"]
|
||||
extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"]
|
||||
javascript = ["esprima (>=4.0.1,<5.0.0)"]
|
||||
llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"]
|
||||
openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"]
|
||||
|
|
@ -549,21 +609,21 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"]
|
|||
|
||||
[[package]]
|
||||
name = "langchain-community"
|
||||
version = "0.0.16"
|
||||
version = "0.0.28"
|
||||
description = "Community contributed LangChain integrations."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langchain_community-0.0.16-py3-none-any.whl", hash = "sha256:0f1dfc1a6205ce8d39931d3515974a208a9f69c16157c649f83490a7cc830b73"},
|
||||
{file = "langchain_community-0.0.16.tar.gz", hash = "sha256:c06512a93013a06fba7679cd5a1254ff8b927cddd2d1fbe0cc444bf7bbdf0b8c"},
|
||||
{file = "langchain_community-0.0.28-py3-none-any.whl", hash = "sha256:bdb015ac455ae68432ea104628717583dce041e1abdfcefe86e39f034f5e90b8"},
|
||||
{file = "langchain_community-0.0.28.tar.gz", hash = "sha256:8664d243a90550fc5ddc137b712034e02c8d43afc8d4cc832ba5842b44c864ce"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = ">=3.8.3,<4.0.0"
|
||||
dataclasses-json = ">=0.5.7,<0.7"
|
||||
langchain-core = ">=0.1.16,<0.2"
|
||||
langsmith = ">=0.0.83,<0.1"
|
||||
langchain-core = ">=0.1.31,<0.2.0"
|
||||
langsmith = ">=0.1.0,<0.2.0"
|
||||
numpy = ">=1,<2"
|
||||
PyYAML = ">=5.3"
|
||||
requests = ">=2,<3"
|
||||
|
|
@ -572,24 +632,24 @@ tenacity = ">=8.1.0,<9.0.0"
|
|||
|
||||
[package.extras]
|
||||
cli = ["typer (>=0.9.0,<0.10.0)"]
|
||||
extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "elasticsearch (>=8.12.0,<9.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hdbcli (>=2.19.21,<3.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "oci (>=2.119.1,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)", "zhipuai (>=1.0.7,<2.0.0)"]
|
||||
extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cloudpickle (>=2.0.0)", "cohere (>=4,<5)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "elasticsearch (>=8.12.0,<9.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "friendli-client (>=1.2.4,<2.0.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hdbcli (>=2.19.21,<3.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "httpx (>=0.24.1,<0.25.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "nvidia-riva-client (>=2.14.0,<3.0.0)", "oci (>=2.119.1,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "tidb-vector (>=0.0.3,<1.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "tree-sitter (>=0.20.2,<0.21.0)", "tree-sitter-languages (>=1.8.0,<2.0.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)", "zhipuai (>=1.0.7,<2.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "langchain-core"
|
||||
version = "0.1.17"
|
||||
version = "0.1.31"
|
||||
description = "Building applications with LLMs through composability"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langchain_core-0.1.17-py3-none-any.whl", hash = "sha256:026155cf97867bde410ab1834799ab4c5ba64c39380f2a4328bcf9c78623ca64"},
|
||||
{file = "langchain_core-0.1.17.tar.gz", hash = "sha256:59016e457cd6a1708d83a3a454acc97cf02c2a2c3af95626d13f83894fd4e777"},
|
||||
{file = "langchain_core-0.1.31-py3-none-any.whl", hash = "sha256:ff028f00db8ff03565b542cea81be27426022a72c6545b54d8de66fa00948ab3"},
|
||||
{file = "langchain_core-0.1.31.tar.gz", hash = "sha256:d660cf209bb6ce61cb1c853107b091aaa809015a55dce9e0ce19b51d4c8f2a70"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
anyio = ">=3,<5"
|
||||
jsonpatch = ">=1.33,<2.0"
|
||||
langsmith = ">=0.0.83,<0.1"
|
||||
langsmith = ">=0.1.0,<0.2.0"
|
||||
packaging = ">=23.2,<24.0"
|
||||
pydantic = ">=1,<3"
|
||||
PyYAML = ">=5.3"
|
||||
|
|
@ -599,125 +659,159 @@ tenacity = ">=8.1.0,<9.0.0"
|
|||
[package.extras]
|
||||
extended-testing = ["jinja2 (>=3,<4)"]
|
||||
|
||||
[[package]]
|
||||
name = "langchain-text-splitters"
|
||||
version = "0.0.1"
|
||||
description = "LangChain text splitting utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langchain_text_splitters-0.0.1-py3-none-any.whl", hash = "sha256:f5b802f873f5ff6a8b9259ff34d53ed989666ef4e1582e6d1adb3b5520e3839a"},
|
||||
{file = "langchain_text_splitters-0.0.1.tar.gz", hash = "sha256:ac459fa98799f5117ad5425a9330b21961321e30bc19a2a2f9f761ddadd62aa1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
langchain-core = ">=0.1.28,<0.2.0"
|
||||
|
||||
[package.extras]
|
||||
extended-testing = ["lxml (>=5.1.0,<6.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "langsmith"
|
||||
version = "0.0.85"
|
||||
version = "0.1.24"
|
||||
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8.1,<4.0"
|
||||
files = [
|
||||
{file = "langsmith-0.0.85-py3-none-any.whl", hash = "sha256:9d0ccbcda7b69c83828060603a51bb4319e43b8dc807fbd90b6355f8ec709500"},
|
||||
{file = "langsmith-0.0.85.tar.gz", hash = "sha256:fefc631fc30d836b54d4e3f99961c41aea497633898b8f09e305b6c7216c2c54"},
|
||||
{file = "langsmith-0.1.24-py3-none-any.whl", hash = "sha256:898ef5265bca8fc912f7fbf207e1d69cacd86055faecf6811bd42641e6319840"},
|
||||
{file = "langsmith-0.1.24.tar.gz", hash = "sha256:432b829e763f5077df411bc59bb35449813f18174d2ebc8bbbb38427071d5e7d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
orjson = ">=3.9.14,<4.0.0"
|
||||
pydantic = ">=1,<3"
|
||||
requests = ">=2,<3"
|
||||
|
||||
[[package]]
|
||||
name = "marshmallow"
|
||||
version = "3.20.2"
|
||||
version = "3.21.1"
|
||||
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "marshmallow-3.20.2-py3-none-any.whl", hash = "sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9"},
|
||||
{file = "marshmallow-3.20.2.tar.gz", hash = "sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd"},
|
||||
{file = "marshmallow-3.21.1-py3-none-any.whl", hash = "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633"},
|
||||
{file = "marshmallow-3.21.1.tar.gz", hash = "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
packaging = ">=17.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"]
|
||||
docs = ["alabaster (==0.7.15)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"]
|
||||
lint = ["pre-commit (>=2.4,<4.0)"]
|
||||
dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"]
|
||||
docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==4.0.0)", "sphinx-version-warning (==1.1.2)"]
|
||||
tests = ["pytest", "pytz", "simplejson"]
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
version = "6.0.4"
|
||||
version = "6.0.5"
|
||||
description = "multidict implementation"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"},
|
||||
{file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"},
|
||||
{file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"},
|
||||
{file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"},
|
||||
{file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"},
|
||||
{file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"},
|
||||
{file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"},
|
||||
{file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"},
|
||||
{file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"},
|
||||
{file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"},
|
||||
{file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"},
|
||||
{file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"},
|
||||
{file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"},
|
||||
{file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"},
|
||||
{file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -734,48 +828,108 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.26.3"
|
||||
version = "1.26.4"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "numpy-1.26.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-win32.whl", hash = "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3"},
|
||||
{file = "numpy-1.26.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-win32.whl", hash = "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b"},
|
||||
{file = "numpy-1.26.3-cp311-cp311-win_amd64.whl", hash = "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-win32.whl", hash = "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511"},
|
||||
{file = "numpy-1.26.3-cp312-cp312-win_amd64.whl", hash = "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-win32.whl", hash = "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03"},
|
||||
{file = "numpy-1.26.3-cp39-cp39-win_amd64.whl", hash = "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2"},
|
||||
{file = "numpy-1.26.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e"},
|
||||
{file = "numpy-1.26.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0"},
|
||||
{file = "numpy-1.26.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5"},
|
||||
{file = "numpy-1.26.3.tar.gz", hash = "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"},
|
||||
{file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"},
|
||||
{file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"},
|
||||
{file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"},
|
||||
{file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.9.15"
|
||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "orjson-3.9.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d61f7ce4727a9fa7680cd6f3986b0e2c732639f46a5e0156e550e35258aa313a"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4feeb41882e8aa17634b589533baafdceb387e01e117b1ec65534ec724023d04"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fbbeb3c9b2edb5fd044b2a070f127a0ac456ffd079cb82746fc84af01ef021a4"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b66bcc5670e8a6b78f0313bcb74774c8291f6f8aeef10fe70e910b8040f3ab75"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2973474811db7b35c30248d1129c64fd2bdf40d57d84beed2a9a379a6f57d0ab"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fe41b6f72f52d3da4db524c8653e46243c8c92df826ab5ffaece2dba9cccd58"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4228aace81781cc9d05a3ec3a6d2673a1ad0d8725b4e915f1089803e9efd2b99"},
|
||||
{file = "orjson-3.9.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f7b65bfaf69493c73423ce9db66cfe9138b2f9ef62897486417a8fcb0a92bfe"},
|
||||
{file = "orjson-3.9.15-cp310-none-win32.whl", hash = "sha256:2d99e3c4c13a7b0fb3792cc04c2829c9db07838fb6973e578b85c1745e7d0ce7"},
|
||||
{file = "orjson-3.9.15-cp310-none-win_amd64.whl", hash = "sha256:b725da33e6e58e4a5d27958568484aa766e825e93aa20c26c91168be58e08cbb"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c8e8fe01e435005d4421f183038fc70ca85d2c1e490f51fb972db92af6e047c2"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87f1097acb569dde17f246faa268759a71a2cb8c96dd392cd25c668b104cad2f"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff0f9913d82e1d1fadbd976424c316fbc4d9c525c81d047bbdd16bd27dd98cfc"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8055ec598605b0077e29652ccfe9372247474375e0e3f5775c91d9434e12d6b1"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6768a327ea1ba44c9114dba5fdda4a214bdb70129065cd0807eb5f010bfcbb5"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12365576039b1a5a47df01aadb353b68223da413e2e7f98c02403061aad34bde"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:71c6b009d431b3839d7c14c3af86788b3cfac41e969e3e1c22f8a6ea13139404"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e18668f1bd39e69b7fed19fa7cd1cd110a121ec25439328b5c89934e6d30d357"},
|
||||
{file = "orjson-3.9.15-cp311-none-win32.whl", hash = "sha256:62482873e0289cf7313461009bf62ac8b2e54bc6f00c6fabcde785709231a5d7"},
|
||||
{file = "orjson-3.9.15-cp311-none-win_amd64.whl", hash = "sha256:b3d336ed75d17c7b1af233a6561cf421dee41d9204aa3cfcc6c9c65cd5bb69a8"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:82425dd5c7bd3adfe4e94c78e27e2fa02971750c2b7ffba648b0f5d5cc016a73"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c51378d4a8255b2e7c1e5cc430644f0939539deddfa77f6fac7b56a9784160a"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6ae4e06be04dc00618247c4ae3f7c3e561d5bc19ab6941427f6d3722a0875ef7"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcef128f970bb63ecf9a65f7beafd9b55e3aaf0efc271a4154050fc15cdb386e"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b72758f3ffc36ca566ba98a8e7f4f373b6c17c646ff8ad9b21ad10c29186f00d"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c57bc7b946cf2efa67ac55766e41764b66d40cbd9489041e637c1304400494"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:946c3a1ef25338e78107fba746f299f926db408d34553b4754e90a7de1d44068"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2f256d03957075fcb5923410058982aea85455d035607486ccb847f095442bda"},
|
||||
{file = "orjson-3.9.15-cp312-none-win_amd64.whl", hash = "sha256:5bb399e1b49db120653a31463b4a7b27cf2fbfe60469546baf681d1b39f4edf2"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b17f0f14a9c0ba55ff6279a922d1932e24b13fc218a3e968ecdbf791b3682b25"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f6cbd8e6e446fb7e4ed5bac4661a29e43f38aeecbf60c4b900b825a353276a1"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:76bc6356d07c1d9f4b782813094d0caf1703b729d876ab6a676f3aaa9a47e37c"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdfa97090e2d6f73dced247a2f2d8004ac6449df6568f30e7fa1a045767c69a6"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7413070a3e927e4207d00bd65f42d1b780fb0d32d7b1d951f6dc6ade318e1b5a"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cf1596680ac1f01839dba32d496136bdd5d8ffb858c280fa82bbfeb173bdd40"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:809d653c155e2cc4fd39ad69c08fdff7f4016c355ae4b88905219d3579e31eb7"},
|
||||
{file = "orjson-3.9.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:920fa5a0c5175ab14b9c78f6f820b75804fb4984423ee4c4f1e6d748f8b22bc1"},
|
||||
{file = "orjson-3.9.15-cp38-none-win32.whl", hash = "sha256:2b5c0f532905e60cf22a511120e3719b85d9c25d0e1c2a8abb20c4dede3b05a5"},
|
||||
{file = "orjson-3.9.15-cp38-none-win_amd64.whl", hash = "sha256:67384f588f7f8daf040114337d34a5188346e3fae6c38b6a19a2fe8c663a2f9b"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6fc2fe4647927070df3d93f561d7e588a38865ea0040027662e3e541d592811e"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34cbcd216e7af5270f2ffa63a963346845eb71e174ea530867b7443892d77180"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f541587f5c558abd93cb0de491ce99a9ef8d1ae29dd6ab4dbb5a13281ae04cbd"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92255879280ef9c3c0bcb327c5a1b8ed694c290d61a6a532458264f887f052cb"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:05a1f57fb601c426635fcae9ddbe90dfc1ed42245eb4c75e4960440cac667262"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede0bde16cc6e9b96633df1631fbcd66491d1063667f260a4f2386a098393790"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e88b97ef13910e5f87bcbc4dd7979a7de9ba8702b54d3204ac587e83639c0c2b"},
|
||||
{file = "orjson-3.9.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57d5d8cf9c27f7ef6bc56a5925c7fbc76b61288ab674eb352c26ac780caa5b10"},
|
||||
{file = "orjson-3.9.15-cp39-none-win32.whl", hash = "sha256:001f4eb0ecd8e9ebd295722d0cbedf0748680fb9998d3993abaed2f40587257a"},
|
||||
{file = "orjson-3.9.15-cp39-none-win_amd64.whl", hash = "sha256:ea0b183a5fe6b2b45f3b854b0d19c4e932d6f5934ae1f723b07cf9560edd4ec7"},
|
||||
{file = "orjson-3.9.15.tar.gz", hash = "sha256:95cae920959d772f30ab36d3b25f83bb0f3be671e986c72ce22f8fa700dae061"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -792,19 +946,19 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.6.0"
|
||||
version = "2.6.4"
|
||||
description = "Data validation using Python type hints"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic-2.6.0-py3-none-any.whl", hash = "sha256:1440966574e1b5b99cf75a13bec7b20e3512e8a61b894ae252f56275e2c465ae"},
|
||||
{file = "pydantic-2.6.0.tar.gz", hash = "sha256:ae887bd94eb404b09d86e4d12f93893bdca79d766e738528c6fa1c849f3c6bcf"},
|
||||
{file = "pydantic-2.6.4-py3-none-any.whl", hash = "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5"},
|
||||
{file = "pydantic-2.6.4.tar.gz", hash = "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
annotated-types = ">=0.4.0"
|
||||
pydantic-core = "2.16.1"
|
||||
pydantic-core = "2.16.3"
|
||||
typing-extensions = ">=4.6.1"
|
||||
|
||||
[package.extras]
|
||||
|
|
@ -812,91 +966,91 @@ email = ["email-validator (>=2.0.0)"]
|
|||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.16.1"
|
||||
version = "2.16.3"
|
||||
description = ""
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:300616102fb71241ff477a2cbbc847321dbec49428434a2f17f37528721c4948"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5511f962dd1b9b553e9534c3b9c6a4b0c9ded3d8c2be96e61d56f933feef9e1f"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98f0edee7ee9cc7f9221af2e1b95bd02810e1c7a6d115cfd82698803d385b28f"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9795f56aa6b2296f05ac79d8a424e94056730c0b860a62b0fdcfe6340b658cc8"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c45f62e4107ebd05166717ac58f6feb44471ed450d07fecd90e5f69d9bf03c48"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:462d599299c5971f03c676e2b63aa80fec5ebc572d89ce766cd11ca8bcb56f3f"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ebaa4bf6386a3b22eec518da7d679c8363fb7fb70cf6972161e5542f470798"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:99f9a50b56713a598d33bc23a9912224fc5d7f9f292444e6664236ae471ddf17"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8ec364e280db4235389b5e1e6ee924723c693cbc98e9d28dc1767041ff9bc388"},
|
||||
{file = "pydantic_core-2.16.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:653a5dfd00f601a0ed6654a8b877b18d65ac32c9d9997456e0ab240807be6cf7"},
|
||||
{file = "pydantic_core-2.16.1-cp310-none-win32.whl", hash = "sha256:1661c668c1bb67b7cec96914329d9ab66755911d093bb9063c4c8914188af6d4"},
|
||||
{file = "pydantic_core-2.16.1-cp310-none-win_amd64.whl", hash = "sha256:561be4e3e952c2f9056fba5267b99be4ec2afadc27261505d4992c50b33c513c"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:102569d371fadc40d8f8598a59379c37ec60164315884467052830b28cc4e9da"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:735dceec50fa907a3c314b84ed609dec54b76a814aa14eb90da31d1d36873a5e"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e83ebbf020be727d6e0991c1b192a5c2e7113eb66e3def0cd0c62f9f266247e4"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:30a8259569fbeec49cfac7fda3ec8123486ef1b729225222f0d41d5f840b476f"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920c4897e55e2881db6a6da151198e5001552c3777cd42b8a4c2f72eedc2ee91"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5247a3d74355f8b1d780d0f3b32a23dd9f6d3ff43ef2037c6dcd249f35ecf4c"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5bea8012df5bb6dda1e67d0563ac50b7f64a5d5858348b5c8cb5043811c19d"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ed3025a8a7e5a59817b7494686d449ebfbe301f3e757b852c8d0d1961d6be864"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06f0d5a1d9e1b7932477c172cc720b3b23c18762ed7a8efa8398298a59d177c7"},
|
||||
{file = "pydantic_core-2.16.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:150ba5c86f502c040b822777e2e519b5625b47813bd05f9273a8ed169c97d9ae"},
|
||||
{file = "pydantic_core-2.16.1-cp311-none-win32.whl", hash = "sha256:d6cbdf12ef967a6aa401cf5cdf47850559e59eedad10e781471c960583f25aa1"},
|
||||
{file = "pydantic_core-2.16.1-cp311-none-win_amd64.whl", hash = "sha256:afa01d25769af33a8dac0d905d5c7bb2d73c7c3d5161b2dd6f8b5b5eea6a3c4c"},
|
||||
{file = "pydantic_core-2.16.1-cp311-none-win_arm64.whl", hash = "sha256:1a2fe7b00a49b51047334d84aafd7e39f80b7675cad0083678c58983662da89b"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f478ec204772a5c8218e30eb813ca43e34005dff2eafa03931b3d8caef87d51"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1936ef138bed2165dd8573aa65e3095ef7c2b6247faccd0e15186aabdda7f66"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99d3a433ef5dc3021c9534a58a3686c88363c591974c16c54a01af7efd741f13"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd88f40f2294440d3f3c6308e50d96a0d3d0973d6f1a5732875d10f569acef49"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fac641bbfa43d5a1bed99d28aa1fded1984d31c670a95aac1bf1d36ac6ce137"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72bf9308a82b75039b8c8edd2be2924c352eda5da14a920551a8b65d5ee89253"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb4363e6c9fc87365c2bc777a1f585a22f2f56642501885ffc7942138499bf54"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:20f724a023042588d0f4396bbbcf4cffd0ddd0ad3ed4f0d8e6d4ac4264bae81e"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fb4370b15111905bf8b5ba2129b926af9470f014cb0493a67d23e9d7a48348e8"},
|
||||
{file = "pydantic_core-2.16.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23632132f1fd608034f1a56cc3e484be00854db845b3a4a508834be5a6435a6f"},
|
||||
{file = "pydantic_core-2.16.1-cp312-none-win32.whl", hash = "sha256:b9f3e0bffad6e238f7acc20c393c1ed8fab4371e3b3bc311020dfa6020d99212"},
|
||||
{file = "pydantic_core-2.16.1-cp312-none-win_amd64.whl", hash = "sha256:a0b4cfe408cd84c53bab7d83e4209458de676a6ec5e9c623ae914ce1cb79b96f"},
|
||||
{file = "pydantic_core-2.16.1-cp312-none-win_arm64.whl", hash = "sha256:d195add190abccefc70ad0f9a0141ad7da53e16183048380e688b466702195dd"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:502c062a18d84452858f8aea1e520e12a4d5228fc3621ea5061409d666ea1706"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d8c032ccee90b37b44e05948b449a2d6baed7e614df3d3f47fe432c952c21b60"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:920f4633bee43d7a2818e1a1a788906df5a17b7ab6fe411220ed92b42940f818"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f5d37ff01edcbace53a402e80793640c25798fb7208f105d87a25e6fcc9ea06"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:399166f24c33a0c5759ecc4801f040dbc87d412c1a6d6292b2349b4c505effc9"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ac89ccc39cd1d556cc72d6752f252dc869dde41c7c936e86beac5eb555041b66"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73802194f10c394c2bedce7a135ba1d8ba6cff23adf4217612bfc5cf060de34c"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8fa00fa24ffd8c31fac081bf7be7eb495be6d248db127f8776575a746fa55c95"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:601d3e42452cd4f2891c13fa8c70366d71851c1593ed42f57bf37f40f7dca3c8"},
|
||||
{file = "pydantic_core-2.16.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07982b82d121ed3fc1c51faf6e8f57ff09b1325d2efccaa257dd8c0dd937acca"},
|
||||
{file = "pydantic_core-2.16.1-cp38-none-win32.whl", hash = "sha256:d0bf6f93a55d3fa7a079d811b29100b019784e2ee6bc06b0bb839538272a5610"},
|
||||
{file = "pydantic_core-2.16.1-cp38-none-win_amd64.whl", hash = "sha256:fbec2af0ebafa57eb82c18c304b37c86a8abddf7022955d1742b3d5471a6339e"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a497be217818c318d93f07e14502ef93d44e6a20c72b04c530611e45e54c2196"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:694a5e9f1f2c124a17ff2d0be613fd53ba0c26de588eb4bdab8bca855e550d95"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d4dfc66abea3ec6d9f83e837a8f8a7d9d3a76d25c9911735c76d6745950e62c"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8655f55fe68c4685673265a650ef71beb2d31871c049c8b80262026f23605ee3"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21e3298486c4ea4e4d5cc6fb69e06fb02a4e22089304308817035ac006a7f506"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71b4a48a7427f14679f0015b13c712863d28bb1ab700bd11776a5368135c7d60"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dca874e35bb60ce4f9f6665bfbfad050dd7573596608aeb9e098621ac331dc"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fa496cd45cda0165d597e9d6f01e36c33c9508f75cf03c0a650018c5048f578e"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5317c04349472e683803da262c781c42c5628a9be73f4750ac7d13040efb5d2d"},
|
||||
{file = "pydantic_core-2.16.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:42c29d54ed4501a30cd71015bf982fa95e4a60117b44e1a200290ce687d3e640"},
|
||||
{file = "pydantic_core-2.16.1-cp39-none-win32.whl", hash = "sha256:ba07646f35e4e49376c9831130039d1b478fbfa1215ae62ad62d2ee63cf9c18f"},
|
||||
{file = "pydantic_core-2.16.1-cp39-none-win_amd64.whl", hash = "sha256:2133b0e412a47868a358713287ff9f9a328879da547dc88be67481cdac529118"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d25ef0c33f22649b7a088035fd65ac1ce6464fa2876578df1adad9472f918a76"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:99c095457eea8550c9fa9a7a992e842aeae1429dab6b6b378710f62bfb70b394"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b49c604ace7a7aa8af31196abbf8f2193be605db6739ed905ecaf62af31ccae0"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c56da23034fe66221f2208c813d8aa509eea34d97328ce2add56e219c3a9f41c"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cebf8d56fee3b08ad40d332a807ecccd4153d3f1ba8231e111d9759f02edfd05"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:1ae8048cba95f382dba56766525abca438328455e35c283bb202964f41a780b0"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:780daad9e35b18d10d7219d24bfb30148ca2afc309928e1d4d53de86822593dc"},
|
||||
{file = "pydantic_core-2.16.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c94b5537bf6ce66e4d7830c6993152940a188600f6ae044435287753044a8fe2"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:adf28099d061a25fbcc6531febb7a091e027605385de9fe14dd6a97319d614cf"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:644904600c15816a1f9a1bafa6aab0d21db2788abcdf4e2a77951280473f33e1"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87bce04f09f0552b66fca0c4e10da78d17cb0e71c205864bab4e9595122cb9d9"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:877045a7969ace04d59516d5d6a7dee13106822f99a5d8df5e6822941f7bedc8"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9c46e556ee266ed3fb7b7a882b53df3c76b45e872fdab8d9cf49ae5e91147fd7"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4eebbd049008eb800f519578e944b8dc8e0f7d59a5abb5924cc2d4ed3a1834ff"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:c0be58529d43d38ae849a91932391eb93275a06b93b79a8ab828b012e916a206"},
|
||||
{file = "pydantic_core-2.16.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b1fc07896fc1851558f532dffc8987e526b682ec73140886c831d773cef44b76"},
|
||||
{file = "pydantic_core-2.16.1.tar.gz", hash = "sha256:daff04257b49ab7f4b3f73f98283d3dbb1a65bf3500d55c7beac3c66c310fe34"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"},
|
||||
{file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"},
|
||||
{file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"},
|
||||
{file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"},
|
||||
{file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"},
|
||||
{file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"},
|
||||
{file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"},
|
||||
{file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"},
|
||||
{file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"},
|
||||
{file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"},
|
||||
{file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"},
|
||||
{file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"},
|
||||
{file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"},
|
||||
{file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"},
|
||||
{file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"},
|
||||
{file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"},
|
||||
{file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"},
|
||||
{file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"},
|
||||
{file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"},
|
||||
{file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"},
|
||||
{file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -956,7 +1110,7 @@ files = [
|
|||
name = "requests"
|
||||
version = "2.31.0"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
|
@ -976,73 +1130,73 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
|||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
description = "Sniff out which async library your code is running under"
|
||||
category = "dev"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
|
||||
{file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
|
||||
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
||||
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "2.0.25"
|
||||
version = "2.0.28"
|
||||
description = "Database Abstraction Library"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"},
|
||||
{file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"},
|
||||
{file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"},
|
||||
{file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"},
|
||||
{file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"},
|
||||
{file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"},
|
||||
{file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"},
|
||||
{file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"},
|
||||
{file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0b148ab0438f72ad21cb004ce3bdaafd28465c4276af66df3b9ecd2037bf252"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbda76961eb8f27e6ad3c84d1dc56d5bc61ba8f02bd20fcf3450bd421c2fcc9c"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feea693c452d85ea0015ebe3bb9cd15b6f49acc1a31c28b3c50f4db0f8fb1e71"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5da98815f82dce0cb31fd1e873a0cb30934971d15b74e0d78cf21f9e1b05953f"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5adf383c73f2d49ad15ff363a8748319ff84c371eed59ffd0127355d6ea1da"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56856b871146bfead25fbcaed098269d90b744eea5cb32a952df00d542cdd368"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-win32.whl", hash = "sha256:943aa74a11f5806ab68278284a4ddd282d3fb348a0e96db9b42cb81bf731acdc"},
|
||||
{file = "SQLAlchemy-2.0.28-cp310-cp310-win_amd64.whl", hash = "sha256:c6c4da4843e0dabde41b8f2e8147438330924114f541949e6318358a56d1875a"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46a3d4e7a472bfff2d28db838669fc437964e8af8df8ee1e4548e92710929adc"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3dd67b5d69794cfe82862c002512683b3db038b99002171f624712fa71aeaa"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61e2e41656a673b777e2f0cbbe545323dbe0d32312f590b1bc09da1de6c2a02"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0315d9125a38026227f559488fe7f7cee1bd2fbc19f9fd637739dc50bb6380b2"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af8ce2d31679006e7b747d30a89cd3ac1ec304c3d4c20973f0f4ad58e2d1c4c9"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:81ba314a08c7ab701e621b7ad079c0c933c58cdef88593c59b90b996e8b58fa5"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-win32.whl", hash = "sha256:1ee8bd6d68578e517943f5ebff3afbd93fc65f7ef8f23becab9fa8fb315afb1d"},
|
||||
{file = "SQLAlchemy-2.0.28-cp311-cp311-win_amd64.whl", hash = "sha256:ad7acbe95bac70e4e687a4dc9ae3f7a2f467aa6597049eeb6d4a662ecd990bb6"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d3499008ddec83127ab286c6f6ec82a34f39c9817f020f75eca96155f9765097"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b66fcd38659cab5d29e8de5409cdf91e9986817703e1078b2fdaad731ea66f5"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea30da1e76cb1acc5b72e204a920a3a7678d9d52f688f087dc08e54e2754c67"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:124202b4e0edea7f08a4db8c81cc7859012f90a0d14ba2bf07c099aff6e96462"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e23b88c69497a6322b5796c0781400692eca1ae5532821b39ce81a48c395aae9"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b6303bfd78fb3221847723104d152e5972c22367ff66edf09120fcde5ddc2e2"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-win32.whl", hash = "sha256:a921002be69ac3ab2cf0c3017c4e6a3377f800f1fca7f254c13b5f1a2f10022c"},
|
||||
{file = "SQLAlchemy-2.0.28-cp312-cp312-win_amd64.whl", hash = "sha256:b4a2cf92995635b64876dc141af0ef089c6eea7e05898d8d8865e71a326c0385"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e91b5e341f8c7f1e5020db8e5602f3ed045a29f8e27f7f565e0bdee3338f2c7"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c7b78dfc7278329f27be02c44abc0d69fe235495bb8e16ec7ef1b1a17952db"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eba73ef2c30695cb7eabcdb33bb3d0b878595737479e152468f3ba97a9c22a4"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5df5d1dafb8eee89384fb7a1f79128118bc0ba50ce0db27a40750f6f91aa99d5"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2858bbab1681ee5406650202950dc8f00e83b06a198741b7c656e63818633526"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-win32.whl", hash = "sha256:9461802f2e965de5cff80c5a13bc945abea7edaa1d29360b485c3d2b56cdb075"},
|
||||
{file = "SQLAlchemy-2.0.28-cp37-cp37m-win_amd64.whl", hash = "sha256:a6bec1c010a6d65b3ed88c863d56b9ea5eeefdf62b5e39cafd08c65f5ce5198b"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:843a882cadebecc655a68bd9a5b8aa39b3c52f4a9a5572a3036fb1bb2ccdc197"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dbb990612c36163c6072723523d2be7c3eb1517bbdd63fe50449f56afafd1133"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7e4baf9161d076b9a7e432fce06217b9bd90cfb8f1d543d6e8c4595627edb9"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0a5354cb4de9b64bccb6ea33162cb83e03dbefa0d892db88a672f5aad638a75"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fffcc8edc508801ed2e6a4e7b0d150a62196fd28b4e16ab9f65192e8186102b6"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aca7b6d99a4541b2ebab4494f6c8c2f947e0df4ac859ced575238e1d6ca5716b"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-win32.whl", hash = "sha256:8c7f10720fc34d14abad5b647bc8202202f4948498927d9f1b4df0fb1cf391b7"},
|
||||
{file = "SQLAlchemy-2.0.28-cp38-cp38-win_amd64.whl", hash = "sha256:243feb6882b06a2af68ecf4bec8813d99452a1b62ba2be917ce6283852cf701b"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc4974d3684f28b61b9a90fcb4c41fb340fd4b6a50c04365704a4da5a9603b05"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87724e7ed2a936fdda2c05dbd99d395c91ea3c96f029a033a4a20e008dd876bf"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68722e6a550f5de2e3cfe9da6afb9a7dd15ef7032afa5651b0f0c6b3adb8815d"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328529f7c7f90adcd65aed06a161851f83f475c2f664a898af574893f55d9e53"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:df40c16a7e8be7413b885c9bf900d402918cc848be08a59b022478804ea076b8"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:426f2fa71331a64f5132369ede5171c52fd1df1bd9727ce621f38b5b24f48750"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-win32.whl", hash = "sha256:33157920b233bc542ce497a81a2e1452e685a11834c5763933b440fedd1d8e2d"},
|
||||
{file = "SQLAlchemy-2.0.28-cp39-cp39-win_amd64.whl", hash = "sha256:2f60843068e432311c886c5f03c4664acaef507cf716f6c60d5fde7265be9d7b"},
|
||||
{file = "SQLAlchemy-2.0.28-py3-none-any.whl", hash = "sha256:78bb7e8da0183a8301352d569900d9d3594c48ac21dc1c2ec6b3121ed8b6c986"},
|
||||
{file = "SQLAlchemy-2.0.28.tar.gz", hash = "sha256:dd53b6c4e6d960600fd6532b79ee28e2da489322fcf6648738134587faf767b6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -1091,14 +1245,14 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"]
|
|||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.9.0"
|
||||
version = "4.10.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
|
||||
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
||||
{file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
|
||||
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1119,14 +1273,14 @@ typing-extensions = ">=3.7.4"
|
|||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.0"
|
||||
version = "2.2.1"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"},
|
||||
{file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"},
|
||||
{file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
|
||||
{file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import os
|
|||
from uuid import uuid1
|
||||
import discord
|
||||
from honcho import Honcho
|
||||
from honcho.ext.langchain import langchain_message_converter
|
||||
from graph import chat
|
||||
from dspy import Example
|
||||
from chain import langchain_message_converter
|
||||
|
||||
intents = discord.Intents.default()
|
||||
intents.messages = True
|
||||
|
|
@ -51,7 +51,9 @@ async def on_message(message):
|
|||
user = honcho.get_or_create_user(user_id)
|
||||
location_id = str(message.channel.id)
|
||||
|
||||
sessions = list(user.get_sessions_generator(location_id, is_active=True, reverse=True))
|
||||
sessions = list(
|
||||
user.get_sessions_generator(location_id, is_active=True, reverse=True)
|
||||
)
|
||||
|
||||
if len(sessions) > 0:
|
||||
session = sessions[0]
|
||||
|
|
@ -86,7 +88,9 @@ async def on_reaction_add(reaction, user):
|
|||
honcho_user = honcho.get_or_create_user(user_id)
|
||||
location_id = str(reaction.message.channel.id)
|
||||
|
||||
sessions = list(honcho_user.get_sessions_generator(location_id, is_active=True, reverse=True))
|
||||
sessions = list(
|
||||
honcho_user.get_sessions_generator(location_id, is_active=True, reverse=True)
|
||||
)
|
||||
if len(sessions) > 0:
|
||||
session = sessions[0]
|
||||
else:
|
||||
|
|
@ -100,25 +104,29 @@ async def on_reaction_add(reaction, user):
|
|||
user_response = user_responses[0]
|
||||
|
||||
user_state_storage = dict(honcho_user.metadata)
|
||||
user_state = list(session.get_metamessages_generator(metamessage_type="user_state", message=user_response, reverse=True))[0].content
|
||||
user_state = list(
|
||||
session.get_metamessages_generator(
|
||||
metamessage_type="user_state", message=user_response, reverse=True
|
||||
)
|
||||
)[0].content
|
||||
examples = user_state_storage[user_state]["examples"]
|
||||
|
||||
# Check if the reaction is a thumbs up
|
||||
if str(reaction.emoji) == "👍":
|
||||
example = Example(
|
||||
chat_input=user_response.content,
|
||||
chat_input=user_response.content,
|
||||
response=ai_response,
|
||||
assessment_dimension=user_state,
|
||||
label='yes'
|
||||
label="yes",
|
||||
).with_inputs("chat_input", "response", "assessment_dimension")
|
||||
examples.append(example.toDict())
|
||||
# Check if the reaction is a thumbs down
|
||||
elif str(reaction.emoji) == "👎":
|
||||
example = Example(
|
||||
chat_input=user_response.content,
|
||||
chat_input=user_response.content,
|
||||
response=ai_response,
|
||||
assessment_dimension=user_state,
|
||||
label='no'
|
||||
label="no",
|
||||
).with_inputs("chat_input", "response", "assessment_dimension")
|
||||
examples.append(example.toDict())
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ import os
|
|||
from typing import List, Union
|
||||
from dotenv import load_dotenv
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, load_prompt
|
||||
from langchain_core.prompts import (
|
||||
ChatPromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
load_prompt,
|
||||
)
|
||||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
|
||||
from honcho import Message
|
||||
|
|
@ -10,84 +14,103 @@ from honcho import Message
|
|||
load_dotenv()
|
||||
|
||||
# langchain prompts
|
||||
SYSTEM_STATE_COMMENTARY = load_prompt(os.path.join(os.path.dirname(__file__), 'langchain_prompts/state_commentary.yaml'))
|
||||
SYSTEM_STATE_LABELING = load_prompt(os.path.join(os.path.dirname(__file__), 'langchain_prompts/state_labeling.yaml'))
|
||||
SYSTEM_STATE_CHECK = load_prompt(os.path.join(os.path.dirname(__file__), 'langchain_prompts/state_check.yaml'))
|
||||
|
||||
# quick utility function to convert messages from honcho to langchain
|
||||
def langchain_message_converter(messages: List[Message]) -> List[Union[AIMessage, HumanMessage]]:
|
||||
new_messages = []
|
||||
for message in messages:
|
||||
if message.is_user:
|
||||
new_messages.append(HumanMessage(content=message.content))
|
||||
else:
|
||||
new_messages.append(AIMessage(content=message.content))
|
||||
return new_messages
|
||||
SYSTEM_STATE_COMMENTARY = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "langchain_prompts/state_commentary.yaml")
|
||||
)
|
||||
SYSTEM_STATE_LABELING = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "langchain_prompts/state_labeling.yaml")
|
||||
)
|
||||
SYSTEM_STATE_CHECK = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "langchain_prompts/state_check.yaml")
|
||||
)
|
||||
|
||||
|
||||
# convert chat history and user input into a string
|
||||
def format_chat_history(chat_history: List[Message], user_input=None):
|
||||
messages = [("user: " + message.content if isinstance(message, HumanMessage) else "ai: " + message.content) for message in chat_history]
|
||||
messages = [
|
||||
(
|
||||
"user: " + message.content
|
||||
if isinstance(message, HumanMessage)
|
||||
else "ai: " + message.content
|
||||
)
|
||||
for message in chat_history
|
||||
]
|
||||
if user_input:
|
||||
messages.append(f"user: {user_input}")
|
||||
|
||||
return "\n".join(messages)
|
||||
|
||||
|
||||
|
||||
class StateExtractor:
|
||||
"""Wrapper class for all the DSPy and LangChain code for user state labeling and pipeline optimization"""
|
||||
lc_gpt_4: ChatOpenAI = ChatOpenAI(model_name = "gpt-4")
|
||||
lc_gpt_turbo: ChatOpenAI = ChatOpenAI(model_name = "gpt-3.5-turbo")
|
||||
system_state_commentary: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_STATE_COMMENTARY)
|
||||
system_state_labeling: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_STATE_LABELING)
|
||||
system_state_check: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_STATE_CHECK)
|
||||
|
||||
lc_gpt_4: ChatOpenAI = ChatOpenAI(model_name="gpt-4")
|
||||
lc_gpt_turbo: ChatOpenAI = ChatOpenAI(model_name="gpt-3.5-turbo")
|
||||
system_state_commentary: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_STATE_COMMENTARY
|
||||
)
|
||||
system_state_labeling: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_STATE_LABELING
|
||||
)
|
||||
system_state_check: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_STATE_CHECK
|
||||
)
|
||||
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
async def generate_state_commentary(cls, existing_states: List[str], chat_history: List[Message], input: str) -> str:
|
||||
async def generate_state_commentary(
|
||||
cls, existing_states: List[str], chat_history: List[Message], input: str
|
||||
) -> str:
|
||||
"""Generate a commentary on the current state of the user"""
|
||||
# format existing states
|
||||
existing_states = "\n".join(existing_states)
|
||||
# format prompt
|
||||
state_commentary = ChatPromptTemplate.from_messages([
|
||||
cls.system_state_commentary
|
||||
])
|
||||
state_commentary = ChatPromptTemplate.from_messages(
|
||||
[cls.system_state_commentary]
|
||||
)
|
||||
# LCEL
|
||||
chain = state_commentary | cls.lc_gpt_4
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"chat_history": chat_history,
|
||||
"user_input": input,
|
||||
"existing_states": existing_states,
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"chat_history": chat_history,
|
||||
"user_input": input,
|
||||
"existing_states": existing_states,
|
||||
}
|
||||
)
|
||||
# return output
|
||||
return response.content
|
||||
|
||||
|
||||
@classmethod
|
||||
async def generate_state_label(cls, existing_states: List[str], state_commentary: str) -> str:
|
||||
async def generate_state_label(
|
||||
cls, existing_states: List[str], state_commentary: str
|
||||
) -> str:
|
||||
"""Generate a state label from a commetary on the user's state"""
|
||||
# format existing states
|
||||
existing_states = "\n".join(existing_states)
|
||||
# format prompt
|
||||
state_labeling = ChatPromptTemplate.from_messages([
|
||||
cls.system_state_labeling,
|
||||
])
|
||||
state_labeling = ChatPromptTemplate.from_messages(
|
||||
[
|
||||
cls.system_state_labeling,
|
||||
]
|
||||
)
|
||||
# LCEL
|
||||
chain = state_labeling | cls.lc_gpt_4
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"state_commentary": state_commentary,
|
||||
"existing_states": existing_states,
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"state_commentary": state_commentary,
|
||||
"existing_states": existing_states,
|
||||
}
|
||||
)
|
||||
|
||||
# strip anything that's not letters
|
||||
clean_response = ''.join(c for c in response.content if c.isalpha())
|
||||
clean_response = "".join(c for c in response.content if c.isalpha())
|
||||
# return output
|
||||
return clean_response
|
||||
|
||||
|
||||
@classmethod
|
||||
async def check_state_exists(cls, existing_states: List[str], state: str):
|
||||
"""Check if a user state is new or already is stored"""
|
||||
|
|
@ -96,32 +119,36 @@ class StateExtractor:
|
|||
existing_states = "\n".join(existing_states)
|
||||
|
||||
# format prompt
|
||||
state_check = ChatPromptTemplate.from_messages([
|
||||
cls.system_state_check
|
||||
])
|
||||
state_check = ChatPromptTemplate.from_messages([cls.system_state_check])
|
||||
# LCEL
|
||||
chain = state_check | cls.lc_gpt_turbo
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"existing_states": existing_states,
|
||||
"state": state,
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"existing_states": existing_states,
|
||||
"state": state,
|
||||
}
|
||||
)
|
||||
# return output
|
||||
return response.content
|
||||
|
||||
@classmethod
|
||||
async def generate_state(cls, existing_states: List[str], chat_history: List[Message], input: str):
|
||||
""""Determine the user's state from the current conversation state"""
|
||||
async def generate_state(
|
||||
cls, existing_states: List[str], chat_history: List[Message], input: str
|
||||
):
|
||||
""" "Determine the user's state from the current conversation state"""
|
||||
|
||||
# Generate label
|
||||
state_commentary = await cls.generate_state_commentary(existing_states, chat_history, input)
|
||||
state_commentary = await cls.generate_state_commentary(
|
||||
existing_states, chat_history, input
|
||||
)
|
||||
state_label = await cls.generate_state_label(existing_states, state_commentary)
|
||||
|
||||
# Determine if state is new
|
||||
# if True, it doesn't exist, state is new
|
||||
# if False, it does exist, state is not new, existing_state was returned
|
||||
existing_state = await cls.check_state_exists(existing_states, state_label)
|
||||
is_state_new = existing_state == "None"
|
||||
is_state_new = existing_state == "None"
|
||||
|
||||
# return existing state if we found one
|
||||
if is_state_new:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import os
|
|||
from uuid import uuid1
|
||||
import discord
|
||||
from honcho import Honcho
|
||||
from chain import langchain_message_converter, LMChain
|
||||
from honcho.ext.langchain import langchain_message_converter
|
||||
from chain import LMChain
|
||||
|
||||
|
||||
intents = discord.Intents.default()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ import os
|
|||
from typing import List
|
||||
from dotenv import load_dotenv
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, load_prompt
|
||||
from langchain_core.prompts import (
|
||||
ChatPromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
load_prompt,
|
||||
)
|
||||
from langchain_core.output_parsers import NumberedListOutputParser
|
||||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
|
||||
|
|
@ -10,30 +14,37 @@ from honcho import Collection, Session, Message
|
|||
|
||||
load_dotenv()
|
||||
|
||||
SYSTEM_DERIVE_FACTS = load_prompt(os.path.join(os.path.dirname(__file__), 'prompts/core/derive_facts.yaml'))
|
||||
SYSTEM_INTROSPECTION = load_prompt(os.path.join(os.path.dirname(__file__), 'prompts/core/introspection.yaml'))
|
||||
SYSTEM_RESPONSE = load_prompt(os.path.join(os.path.dirname(__file__), 'prompts/core/response.yaml'))
|
||||
SYSTEM_CHECK_DUPS = load_prompt(os.path.join(os.path.dirname(__file__), 'prompts/utils/check_dup_facts.yaml'))
|
||||
|
||||
|
||||
def langchain_message_converter(messages: List):
|
||||
new_messages = []
|
||||
for message in messages:
|
||||
if message.is_user:
|
||||
new_messages.append(HumanMessage(content=message.content))
|
||||
else:
|
||||
new_messages.append(AIMessage(content=message.content))
|
||||
return new_messages
|
||||
SYSTEM_DERIVE_FACTS = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/core/derive_facts.yaml")
|
||||
)
|
||||
SYSTEM_INTROSPECTION = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/core/introspection.yaml")
|
||||
)
|
||||
SYSTEM_RESPONSE = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/core/response.yaml")
|
||||
)
|
||||
SYSTEM_CHECK_DUPS = load_prompt(
|
||||
os.path.join(os.path.dirname(__file__), "prompts/utils/check_dup_facts.yaml")
|
||||
)
|
||||
|
||||
|
||||
class LMChain:
|
||||
"Wrapper class for encapsulating the multiple different chains used"
|
||||
|
||||
output_parser = NumberedListOutputParser()
|
||||
llm: ChatOpenAI = ChatOpenAI(model_name = "gpt-3.5-turbo")
|
||||
system_derive_facts: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_DERIVE_FACTS)
|
||||
system_introspection: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_INTROSPECTION)
|
||||
system_response: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_RESPONSE)
|
||||
system_check_dups: SystemMessagePromptTemplate = SystemMessagePromptTemplate(prompt=SYSTEM_CHECK_DUPS)
|
||||
llm: ChatOpenAI = ChatOpenAI(model_name="gpt-3.5-turbo")
|
||||
system_derive_facts: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_DERIVE_FACTS
|
||||
)
|
||||
system_introspection: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_INTROSPECTION
|
||||
)
|
||||
system_response: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_RESPONSE
|
||||
)
|
||||
system_check_dups: SystemMessagePromptTemplate = SystemMessagePromptTemplate(
|
||||
prompt=SYSTEM_CHECK_DUPS
|
||||
)
|
||||
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
|
@ -43,18 +54,25 @@ class LMChain:
|
|||
"""Derive facts from the user input"""
|
||||
|
||||
# format prompt
|
||||
fact_derivation = ChatPromptTemplate.from_messages([
|
||||
cls.system_derive_facts
|
||||
])
|
||||
fact_derivation = ChatPromptTemplate.from_messages([cls.system_derive_facts])
|
||||
|
||||
# LCEL
|
||||
chain = fact_derivation | cls.llm
|
||||
|
||||
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"chat_history": [("user: " + message.content if isinstance(message, HumanMessage) else "ai: " + message.content) for message in chat_history],
|
||||
"user_input": input
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"chat_history": [
|
||||
(
|
||||
"user: " + message.content
|
||||
if isinstance(message, HumanMessage)
|
||||
else "ai: " + message.content
|
||||
)
|
||||
for message in chat_history
|
||||
],
|
||||
"user_input": input,
|
||||
}
|
||||
)
|
||||
|
||||
# parse output
|
||||
facts = cls.output_parser.parse(response.content)
|
||||
|
|
@ -62,28 +80,31 @@ class LMChain:
|
|||
print(f"DERIVED FACTS: {facts}")
|
||||
|
||||
return facts
|
||||
|
||||
|
||||
@classmethod
|
||||
async def check_dups(cls, user_message: Message, session: Session, collection: Collection, facts: List):
|
||||
async def check_dups(
|
||||
cls,
|
||||
user_message: Message,
|
||||
session: Session,
|
||||
collection: Collection,
|
||||
facts: List,
|
||||
):
|
||||
"""Check that we're not storing duplicate facts"""
|
||||
|
||||
# format prompt
|
||||
check_duplication = ChatPromptTemplate.from_messages([
|
||||
cls.system_check_dups
|
||||
])
|
||||
check_duplication = ChatPromptTemplate.from_messages([cls.system_check_dups])
|
||||
|
||||
query = " ".join(facts)
|
||||
result = collection.query(query=query, top_k=10)
|
||||
result = collection.query(query=query, top_k=10)
|
||||
existing_facts = [document.content for document in result]
|
||||
|
||||
# LCEL
|
||||
chain = check_duplication | cls.llm
|
||||
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"existing_facts": existing_facts,
|
||||
"facts": facts
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{"existing_facts": existing_facts, "facts": facts}
|
||||
)
|
||||
|
||||
# parse output
|
||||
new_facts = cls.output_parser.parse(response.content)
|
||||
|
|
@ -96,28 +117,30 @@ class LMChain:
|
|||
|
||||
# add facts as metamessages
|
||||
for fact in new_facts:
|
||||
session.create_metamessage(message=user_message, metamessage_type="fact", content=fact)
|
||||
session.create_metamessage(
|
||||
message=user_message, metamessage_type="fact", content=fact
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@classmethod
|
||||
async def introspect(cls, user_message: Message, session: Session, chat_history: List, input:str):
|
||||
async def introspect(
|
||||
cls, user_message: Message, session: Session, chat_history: List, input: str
|
||||
):
|
||||
"""Generate questions about the user to use as retrieval over the fact store"""
|
||||
|
||||
# format prompt
|
||||
introspection_prompt = ChatPromptTemplate.from_messages([
|
||||
cls.system_introspection
|
||||
])
|
||||
introspection_prompt = ChatPromptTemplate.from_messages(
|
||||
[cls.system_introspection]
|
||||
)
|
||||
|
||||
# LCEL
|
||||
chain = introspection_prompt | cls.llm
|
||||
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"chat_history": chat_history,
|
||||
"user_input": input
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{"chat_history": chat_history, "user_input": input}
|
||||
)
|
||||
|
||||
# parse output
|
||||
questions = cls.output_parser.parse(response.content)
|
||||
|
|
@ -126,21 +149,22 @@ class LMChain:
|
|||
|
||||
# write questions as metamessages
|
||||
for question in questions:
|
||||
session.create_metamessage(message=user_message, metamessage_type="introspect", content=question)
|
||||
session.create_metamessage(
|
||||
message=user_message, metamessage_type="introspect", content=question
|
||||
)
|
||||
|
||||
return questions
|
||||
|
||||
|
||||
@classmethod
|
||||
async def respond(cls, collection: Collection, chat_history: List, questions: List, input: str):
|
||||
async def respond(
|
||||
cls, collection: Collection, chat_history: List, questions: List, input: str
|
||||
):
|
||||
"""Take the facts and chat history and generate a personalized response"""
|
||||
|
||||
# format prompt
|
||||
response_prompt = ChatPromptTemplate.from_messages([
|
||||
cls.system_response,
|
||||
*chat_history,
|
||||
HumanMessage(content=input)
|
||||
])
|
||||
response_prompt = ChatPromptTemplate.from_messages(
|
||||
[cls.system_response, *chat_history, HumanMessage(content=input)]
|
||||
)
|
||||
|
||||
retrieved_facts = collection.query(query=questions, top_k=10)
|
||||
retrieved_facts_content = [document.content for document in retrieved_facts]
|
||||
|
|
@ -149,18 +173,29 @@ class LMChain:
|
|||
chain = response_prompt | cls.llm
|
||||
|
||||
# inference
|
||||
response = await chain.ainvoke({
|
||||
"facts": retrieved_facts_content,
|
||||
})
|
||||
response = await chain.ainvoke(
|
||||
{
|
||||
"facts": retrieved_facts_content,
|
||||
}
|
||||
)
|
||||
|
||||
return response.content
|
||||
|
||||
|
||||
@classmethod
|
||||
async def chat(cls, chat_history: List, user_message: Message, session: Session, collection: Collection, input: str):
|
||||
async def chat(
|
||||
cls,
|
||||
chat_history: List,
|
||||
user_message: Message,
|
||||
session: Session,
|
||||
collection: Collection,
|
||||
input: str,
|
||||
):
|
||||
"""Chat with the model"""
|
||||
|
||||
facts = await cls.derive_facts(chat_history, input)
|
||||
await cls.check_dups(user_message, session, collection, facts) if facts is not None else None
|
||||
await cls.check_dups(
|
||||
user_message, session, collection, facts
|
||||
) if facts is not None else None
|
||||
|
||||
# introspect
|
||||
questions = await cls.introspect(user_message, session, chat_history, input)
|
||||
|
|
@ -169,7 +204,3 @@ class LMChain:
|
|||
response = await cls.respond(collection, chat_history, questions, input)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from langchain_core.output_parsers import StrOutputParser
|
|||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
|
||||
from honcho import Honcho
|
||||
from honcho.ext.langchain import langchain_message_converter
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
|
@ -43,16 +44,6 @@ output_parser = StrOutputParser()
|
|||
chain = prompt | model | output_parser
|
||||
|
||||
|
||||
def langchain_message_converter(messages: List):
|
||||
new_messages = []
|
||||
for message in messages:
|
||||
if message.is_user:
|
||||
new_messages.append(HumanMessage(content=message.content))
|
||||
else:
|
||||
new_messages.append(AIMessage(content=message.content))
|
||||
return new_messages
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print(f"We have logged in as {bot.user}")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.0.5] — 2024-03-14
|
||||
|
||||
### Added
|
||||
|
||||
* Metadata to all data primitives (Users, Sessions, Messages, etc.)
|
||||
* Ability to filter paginated GET requests by JSON filter based on metadata
|
||||
* Dialectic API to interact with honcho agent and get insights about users
|
||||
* Code Coverage Tests
|
||||
* Autogenerated Sphinx Documentation for Honcho Client SDK
|
||||
* Built-in Langchain message converter
|
||||
|
||||
### Fixed
|
||||
|
||||
* URL encoding all GET requests in honcho client
|
||||
|
||||
## [0.0.4] — 2024-02-22
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ applications.
|
|||
|
||||
Read about the motivation of this project [here](https://blog.plasticlabs.ai).
|
||||
|
||||
Read the full documentation of this project [here](https://docs.honcho.dev)
|
||||
Read the full documentation of this project [here](https://docs.honcho.dev) and
|
||||
find the SDK reference [here](https://api.python.honcho.dev)
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= poetry run sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
import os
|
||||
import sys
|
||||
|
||||
project = "Honcho"
|
||||
copyright = "2024, Plastic Labs"
|
||||
author = "Plastic Labs"
|
||||
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../honcho"))
|
||||
)
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx.ext.viewcode",
|
||||
]
|
||||
autodoc_member_order = "bysource"
|
||||
|
||||
autosummary_generate = True
|
||||
|
||||
templates_path = ["_templates"]
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
viewcode_import = "import honcho"
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = "furo"
|
||||
html_static_path = ["_static"]
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
.. Honcho documentation master file, created by
|
||||
sphinx-quickstart on Wed Mar 13 11:35:31 2024.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to Honcho's documentation!
|
||||
==================================
|
||||
|
||||
.. .. automodule:: honcho.client
|
||||
.. :members:
|
||||
|
||||
.. .. automodule:: honcho.sync_client
|
||||
.. :members:
|
||||
|
||||
.. .. automodule:: honcho.ext.langchain
|
||||
.. :members:
|
||||
|
||||
.. .. autosummary::
|
||||
.. :toctree: _autosummary
|
||||
.. :recursive:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:caption: Contents:
|
||||
|
||||
source/modules
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
honcho.ext package
|
||||
==================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
honcho.ext.langchain module
|
||||
---------------------------
|
||||
|
||||
.. automodule:: honcho.ext.langchain
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: honcho.ext
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
honcho package
|
||||
==============
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
honcho.ext
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
honcho.cache module
|
||||
-------------------
|
||||
|
||||
.. automodule:: honcho.cache
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
honcho.client module
|
||||
--------------------
|
||||
|
||||
.. automodule:: honcho.client
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
honcho.schemas module
|
||||
---------------------
|
||||
|
||||
.. automodule:: honcho.schemas
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
honcho.sync\_client module
|
||||
--------------------------
|
||||
|
||||
.. automodule:: honcho.sync_client
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: honcho
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
honcho
|
||||
======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
honcho
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
|
|
@ -32,7 +33,13 @@ class AsyncGetPage:
|
|||
class AsyncGetUserPage(AsyncGetPage):
|
||||
"""Paginated Results for Get User Requests"""
|
||||
|
||||
def __init__(self, response: dict, honcho: AsyncHoncho, reverse: bool):
|
||||
def __init__(
|
||||
self,
|
||||
response: dict,
|
||||
honcho: AsyncHoncho,
|
||||
filter: Optional[dict],
|
||||
reverse: bool,
|
||||
):
|
||||
"""Constructor for Page Result from User Get Request
|
||||
|
||||
Args:
|
||||
|
|
@ -42,6 +49,7 @@ class AsyncGetUserPage(AsyncGetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.honcho = honcho
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
AsyncUser(
|
||||
|
|
@ -57,7 +65,10 @@ class AsyncGetUserPage(AsyncGetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return await self.honcho.get_users(
|
||||
page=(self.page + 1), page_size=self.page_size, reverse=self.reverse
|
||||
filter=self.filter,
|
||||
page=(self.page + 1),
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -70,6 +81,7 @@ class AsyncGetSessionPage(AsyncGetPage):
|
|||
user: AsyncUser,
|
||||
reverse: bool,
|
||||
location_id: Optional[str],
|
||||
filter: Optional[dict],
|
||||
is_active: bool,
|
||||
):
|
||||
"""Constructor for Page Result from Session Get Request
|
||||
|
|
@ -85,6 +97,7 @@ class AsyncGetSessionPage(AsyncGetPage):
|
|||
self.location_id = location_id
|
||||
self.reverse = reverse
|
||||
self.is_active = is_active
|
||||
self.filter = filter
|
||||
self.items = [
|
||||
AsyncSession(
|
||||
user=user,
|
||||
|
|
@ -99,14 +112,15 @@ class AsyncGetSessionPage(AsyncGetPage):
|
|||
|
||||
async def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
AsyncGetSessionPage | None: Next Page of Results or None if there
|
||||
are no more sessions to retreive from a query
|
||||
AsyncGetSessionPage | None: Next Page of Results or None if there are no more sessions to retreive from a query
|
||||
"""
|
||||
if self.page >= self.pages:
|
||||
return None
|
||||
return await self.user.get_sessions(
|
||||
location_id=self.location_id,
|
||||
filter=self.filter,
|
||||
page=(self.page + 1),
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
|
|
@ -117,7 +131,13 @@ class AsyncGetSessionPage(AsyncGetPage):
|
|||
class AsyncGetMessagePage(AsyncGetPage):
|
||||
"""Paginated Results for Get Session Requests"""
|
||||
|
||||
def __init__(self, response: dict, session: AsyncSession, reverse: bool):
|
||||
def __init__(
|
||||
self,
|
||||
response: dict,
|
||||
session: AsyncSession,
|
||||
filter: Optional[dict],
|
||||
reverse: bool,
|
||||
):
|
||||
"""Constructor for Page Result from Session Get Request
|
||||
|
||||
Args:
|
||||
|
|
@ -127,6 +147,7 @@ class AsyncGetMessagePage(AsyncGetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.session = session
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Message(
|
||||
|
|
@ -134,6 +155,7 @@ class AsyncGetMessagePage(AsyncGetPage):
|
|||
id=message["id"],
|
||||
is_user=message["is_user"],
|
||||
content=message["content"],
|
||||
metadata=message["metadata"],
|
||||
created_at=message["created_at"],
|
||||
)
|
||||
for message in response["items"]
|
||||
|
|
@ -141,6 +163,7 @@ class AsyncGetMessagePage(AsyncGetPage):
|
|||
|
||||
async def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
AsyncGetMessagePage | None: Next Page of Results or None if there
|
||||
are no more messages to retreive from a query
|
||||
|
|
@ -148,7 +171,7 @@ class AsyncGetMessagePage(AsyncGetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return await self.session.get_messages(
|
||||
(self.page + 1), self.page_size, self.reverse
|
||||
self.filter, (self.page + 1), self.page_size, self.reverse
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -157,6 +180,7 @@ class AsyncGetMetamessagePage(AsyncGetPage):
|
|||
self,
|
||||
response: dict,
|
||||
session,
|
||||
filter: Optional[dict],
|
||||
reverse: bool,
|
||||
message_id: Optional[uuid.UUID],
|
||||
metamessage_type: Optional[str],
|
||||
|
|
@ -175,11 +199,13 @@ class AsyncGetMetamessagePage(AsyncGetPage):
|
|||
self.session = session
|
||||
self.message_id = message_id
|
||||
self.metamessage_type = metamessage_type
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Metamessage(
|
||||
id=metamessage["id"],
|
||||
message_id=metamessage["message_id"],
|
||||
metadata=metamessage["metadata"],
|
||||
metamessage_type=metamessage["metamessage_type"],
|
||||
content=metamessage["content"],
|
||||
created_at=metamessage["created_at"],
|
||||
|
|
@ -189,6 +215,7 @@ class AsyncGetMetamessagePage(AsyncGetPage):
|
|||
|
||||
async def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
AsyncGetMetamessagePage | None: Next Page of Results or None if
|
||||
there are no more metamessages to retreive from a query
|
||||
|
|
@ -197,6 +224,7 @@ class AsyncGetMetamessagePage(AsyncGetPage):
|
|||
return None
|
||||
return await self.session.get_metamessages(
|
||||
metamessage_type=self.metamessage_type,
|
||||
filter=self.filter,
|
||||
message=self.message_id,
|
||||
page=(self.page + 1),
|
||||
page_size=self.page_size,
|
||||
|
|
@ -207,7 +235,9 @@ class AsyncGetMetamessagePage(AsyncGetPage):
|
|||
class AsyncGetDocumentPage(AsyncGetPage):
|
||||
"""Paginated results for Get Document requests"""
|
||||
|
||||
def __init__(self, response: dict, collection, reverse: bool) -> None:
|
||||
def __init__(
|
||||
self, response: dict, collection, filter: Optional[dict], reverse: bool
|
||||
) -> None:
|
||||
"""Constructor for Page Result from Document Get Request
|
||||
|
||||
Args:
|
||||
|
|
@ -218,6 +248,7 @@ class AsyncGetDocumentPage(AsyncGetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.collection = collection
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Document(
|
||||
|
|
@ -232,6 +263,7 @@ class AsyncGetDocumentPage(AsyncGetPage):
|
|||
|
||||
async def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
AsyncGetDocumentPage | None: Next Page of Results or None if there
|
||||
are no more sessions to retreive from a query
|
||||
|
|
@ -239,14 +271,19 @@ class AsyncGetDocumentPage(AsyncGetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return await self.collection.get_documents(
|
||||
page=self.page + 1, page_size=self.page_size, reverse=self.reverse
|
||||
filter=self.filter,
|
||||
page=self.page + 1,
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
)
|
||||
|
||||
|
||||
class AsyncGetCollectionPage(AsyncGetPage):
|
||||
"""Paginated results for Get Collection requests"""
|
||||
|
||||
def __init__(self, response: dict, user: AsyncUser, reverse: bool):
|
||||
def __init__(
|
||||
self, response: dict, user: AsyncUser, filter: Optional[dict], reverse: bool
|
||||
):
|
||||
"""Constructor for page result from Get Collection Request
|
||||
|
||||
Args:
|
||||
|
|
@ -256,12 +293,14 @@ class AsyncGetCollectionPage(AsyncGetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.user = user
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
AsyncCollection(
|
||||
user=user,
|
||||
id=collection["id"],
|
||||
name=collection["name"],
|
||||
metadata=collection["metadata"],
|
||||
created_at=collection["created_at"],
|
||||
)
|
||||
for collection in response["items"]
|
||||
|
|
@ -269,6 +308,7 @@ class AsyncGetCollectionPage(AsyncGetPage):
|
|||
|
||||
async def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
AsyncGetCollectionPage | None: Next Page of Results or None if
|
||||
there are no more sessions to retreive from a query
|
||||
|
|
@ -276,6 +316,7 @@ class AsyncGetCollectionPage(AsyncGetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return await self.user.get_collections(
|
||||
filter=self.filter,
|
||||
page=self.page + 1,
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
|
|
@ -390,7 +431,11 @@ class AsyncHoncho:
|
|||
)
|
||||
|
||||
async def get_users(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Get Paginated list of users
|
||||
|
||||
|
|
@ -402,14 +447,24 @@ class AsyncHoncho:
|
|||
Returns:
|
||||
AsyncGetUserPage: Paginated list of users
|
||||
"""
|
||||
url = f"{self.base_url}/users?page={page}&size={page_size}&reverse={reverse}"
|
||||
response = await self.client.get(url)
|
||||
# url = f"{self.base_url}/users?page={page}&size={page_size}&reverse={reverse}"
|
||||
url = f"{self.base_url}/users"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = await self.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return AsyncGetUserPage(data, self, reverse)
|
||||
return AsyncGetUserPage(data, self, filter, reverse)
|
||||
|
||||
async def get_users_generator(
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Shortcut Generator for get_users. Generator to iterate through
|
||||
|
|
@ -424,7 +479,7 @@ class AsyncHoncho:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_user_response = await self.get_users(page, page_size, reverse)
|
||||
get_user_response = await self.get_users(filter, page, page_size, reverse)
|
||||
while True:
|
||||
for session in get_user_response.items:
|
||||
yield session
|
||||
|
|
@ -523,6 +578,7 @@ class AsyncUser:
|
|||
async def get_sessions(
|
||||
self,
|
||||
location_id: Optional[str] = None,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
|
|
@ -542,20 +598,33 @@ class AsyncUser:
|
|||
AsyncGetSessionPage: Page or results for get_sessions query
|
||||
|
||||
"""
|
||||
url = (
|
||||
f"{self.base_url}/sessions?page={page}&size={page_size}&reverse={reverse}&is_active={is_active}"
|
||||
+ (f"&location_id={location_id}" if location_id else "")
|
||||
)
|
||||
response = await self.honcho.client.get(url)
|
||||
# url = (
|
||||
# f"{self.base_url}/sessions?page={page}&size={page_size}&reverse={reverse}&is_active={is_active}"
|
||||
# + (f"&location_id={location_id}" if location_id else "")
|
||||
# )
|
||||
url = f"{self.base_url}/sessions"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
"is_active": is_active,
|
||||
}
|
||||
if location_id:
|
||||
params["location_id"] = location_id
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = await self.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return AsyncGetSessionPage(data, self, reverse, location_id, is_active)
|
||||
return AsyncGetSessionPage(data, self, reverse, location_id, filter, is_active)
|
||||
|
||||
async def get_sessions_generator(
|
||||
self,
|
||||
location_id: Optional[str] = None,
|
||||
reverse: bool = False,
|
||||
is_active: bool = False,
|
||||
filter: Optional[dict] = None,
|
||||
):
|
||||
"""Shortcut Generator for get_sessions. Generator to iterate through
|
||||
all sessions for a user in an app
|
||||
|
|
@ -573,7 +642,7 @@ class AsyncUser:
|
|||
page = 1
|
||||
page_size = 50
|
||||
get_session_response = await self.get_sessions(
|
||||
location_id, page, page_size, reverse, is_active
|
||||
location_id, filter, page, page_size, reverse, is_active
|
||||
)
|
||||
while True:
|
||||
for session in get_session_response.items:
|
||||
|
|
@ -618,6 +687,7 @@ class AsyncUser:
|
|||
async def create_collection(
|
||||
self,
|
||||
name: str,
|
||||
metadata: Optional[dict] = None,
|
||||
):
|
||||
"""Create a collection for a user
|
||||
|
||||
|
|
@ -628,7 +698,9 @@ class AsyncUser:
|
|||
AsyncCollection: The Collection object of the new Collection
|
||||
|
||||
"""
|
||||
data = {"name": name}
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
data = {"name": name, "metadata": metadata}
|
||||
url = f"{self.base_url}/collections"
|
||||
response = await self.honcho.client.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
|
|
@ -637,6 +709,7 @@ class AsyncUser:
|
|||
self,
|
||||
id=data["id"],
|
||||
name=name,
|
||||
metadata=metadata,
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -658,11 +731,16 @@ class AsyncUser:
|
|||
user=self,
|
||||
id=data["id"],
|
||||
name=data["name"],
|
||||
metadata=data["metadata"],
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
async def get_collections(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Return collections associated with a user paginated
|
||||
|
||||
|
|
@ -675,13 +753,24 @@ class AsyncUser:
|
|||
AsyncGetCollectionPage: Page or results for get_collections query
|
||||
|
||||
"""
|
||||
url = f"{self.base_url}/collections?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
response = await self.honcho.client.get(url)
|
||||
# url = f"{self.base_url}/collections?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
url = f"{self.base_url}/collections"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = await self.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return AsyncGetCollectionPage(data, self, reverse)
|
||||
return AsyncGetCollectionPage(data, self, filter, reverse)
|
||||
|
||||
async def get_collections_generator(self, reverse: bool = False):
|
||||
async def get_collections_generator(
|
||||
self, filter: Optional[dict] = None, reverse: bool = False
|
||||
):
|
||||
"""Shortcut Generator for get_sessions. Generator to iterate through
|
||||
all sessions for a user in an app
|
||||
|
||||
|
|
@ -694,7 +783,9 @@ class AsyncUser:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_collection_response = await self.get_collections(page, page_size, reverse)
|
||||
get_collection_response = await self.get_collections(
|
||||
filter, page, page_size, reverse
|
||||
)
|
||||
while True:
|
||||
for collection in get_collection_response.items:
|
||||
yield collection
|
||||
|
|
@ -740,7 +831,9 @@ class AsyncSession:
|
|||
"""Returns whether the session is active - made property to prevent tampering"""
|
||||
return self._is_active
|
||||
|
||||
async def create_message(self, is_user: bool, content: str):
|
||||
async def create_message(
|
||||
self, is_user: bool, content: str, metadata: Optional[dict] = None
|
||||
):
|
||||
"""Adds a message to the session
|
||||
|
||||
Args:
|
||||
|
|
@ -753,7 +846,9 @@ class AsyncSession:
|
|||
"""
|
||||
if not self.is_active:
|
||||
raise Exception("Session is inactive")
|
||||
data = {"is_user": is_user, "content": content}
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
data = {"is_user": is_user, "content": content, "metadata": metadata}
|
||||
url = f"{self.base_url}/messages"
|
||||
response = await self.user.honcho.client.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
|
|
@ -763,6 +858,7 @@ class AsyncSession:
|
|||
id=data["id"],
|
||||
is_user=is_user,
|
||||
content=content,
|
||||
metadata=metadata,
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -785,11 +881,16 @@ class AsyncSession:
|
|||
id=data["id"],
|
||||
is_user=data["is_user"],
|
||||
content=data["content"],
|
||||
metadata=data["metadata"],
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
async def get_messages(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
) -> AsyncGetMessagePage:
|
||||
"""Get all messages for a session
|
||||
|
||||
|
|
@ -802,13 +903,23 @@ class AsyncSession:
|
|||
AsyncGetMessagePage: Page of Message objects
|
||||
|
||||
"""
|
||||
url = f"{self.base_url}/messages?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
response = await self.user.honcho.client.get(url)
|
||||
url = f"{self.base_url}/messages"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = await self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return AsyncGetMessagePage(data, self, reverse)
|
||||
return AsyncGetMessagePage(data, self, filter, reverse)
|
||||
|
||||
async def get_messages_generator(self, reverse: bool = False):
|
||||
async def get_messages_generator(
|
||||
self, filter: Optional[dict] = None, reverse: bool = False
|
||||
):
|
||||
"""Shortcut Generator for get_messages. Generator to iterate through
|
||||
all messages for a session in an app
|
||||
|
||||
|
|
@ -818,7 +929,7 @@ class AsyncSession:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_messages_page = await self.get_messages(page, page_size, reverse)
|
||||
get_messages_page = await self.get_messages(filter, page, page_size, reverse)
|
||||
while True:
|
||||
for message in get_messages_page.items:
|
||||
yield message
|
||||
|
|
@ -830,7 +941,11 @@ class AsyncSession:
|
|||
get_messages_page = new_messages
|
||||
|
||||
async def create_metamessage(
|
||||
self, message: Message, metamessage_type: str, content: str
|
||||
self,
|
||||
message: Message,
|
||||
metamessage_type: str,
|
||||
content: str,
|
||||
metadata: Optional[dict] = None,
|
||||
):
|
||||
"""Adds a metamessage to a session and links it to a specific message
|
||||
|
||||
|
|
@ -845,10 +960,13 @@ class AsyncSession:
|
|||
"""
|
||||
if not self.is_active:
|
||||
raise Exception("Session is inactive")
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
data = {
|
||||
"metamessage_type": metamessage_type,
|
||||
"content": content,
|
||||
"message_id": message.id,
|
||||
"metadata": metadata,
|
||||
}
|
||||
url = f"{self.base_url}/metamessages"
|
||||
response = await self.user.honcho.client.post(url, json=data)
|
||||
|
|
@ -859,6 +977,7 @@ class AsyncSession:
|
|||
message_id=message.id,
|
||||
metamessage_type=metamessage_type,
|
||||
content=content,
|
||||
metadata=metadata,
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -881,6 +1000,7 @@ class AsyncSession:
|
|||
message_id=data["message_id"],
|
||||
metamessage_type=data["metamessage_type"],
|
||||
content=data["content"],
|
||||
metadata=data["metadata"],
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -888,6 +1008,7 @@ class AsyncSession:
|
|||
self,
|
||||
metamessage_type: Optional[str] = None,
|
||||
message: Optional[Message] = None,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
|
|
@ -905,23 +1026,35 @@ class AsyncSession:
|
|||
list[dict]: List of Message objects
|
||||
|
||||
"""
|
||||
url = f"{self.base_url}/metamessages?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
# url = f"{self.base_url}/metamessages?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
url = f"{self.base_url}/metamessages"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if metamessage_type:
|
||||
url += f"&metamessage_type={metamessage_type}"
|
||||
# url += f"&metamessage_type={metamessage_type}"
|
||||
params["metamessage_type"] = metamessage_type
|
||||
if message:
|
||||
url += f"&message_id={message.id}"
|
||||
response = await self.user.honcho.client.get(url)
|
||||
# url += f"&message_id={message.id}"
|
||||
params["message_id"] = message.id
|
||||
if filter is not None:
|
||||
json_metadata = json.dumps(filter)
|
||||
params["filter"] = json_metadata
|
||||
response = await self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
message_id = message.id if message else None
|
||||
return AsyncGetMetamessagePage(
|
||||
data, self, reverse, message_id, metamessage_type
|
||||
data, self, filter, reverse, message_id, metamessage_type
|
||||
)
|
||||
|
||||
async def get_metamessages_generator(
|
||||
self,
|
||||
metamessage_type: Optional[str] = None,
|
||||
message: Optional[Message] = None,
|
||||
filter: Optional[dict] = None,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Shortcut Generator for get_metamessages. Generator to iterate
|
||||
|
|
@ -940,6 +1073,7 @@ class AsyncSession:
|
|||
get_metamessages_page = await self.get_metamessages(
|
||||
metamessage_type=metamessage_type,
|
||||
message=message,
|
||||
filter=filter,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
reverse=reverse,
|
||||
|
|
@ -970,6 +1104,50 @@ class AsyncSession:
|
|||
self.metadata = metadata
|
||||
return success
|
||||
|
||||
async def update_message(self, message: Message, metadata: dict):
|
||||
"""Update the metadata of a message
|
||||
|
||||
Args:
|
||||
message (Message): The message to update
|
||||
metadata (dict): The new metadata for the message
|
||||
|
||||
Returns:
|
||||
boolean: Whether the message was successfully updated
|
||||
"""
|
||||
info = {"metadata": metadata}
|
||||
url = f"{self.base_url}/messages/{message.id}"
|
||||
response = await self.user.honcho.client.put(url, json=info)
|
||||
success = response.status_code < 400
|
||||
message.metadata = metadata
|
||||
return success
|
||||
|
||||
async def update_metamessage(
|
||||
self,
|
||||
metamessage: Metamessage,
|
||||
metamessage_type: Optional[str],
|
||||
metadata: Optional[dict],
|
||||
):
|
||||
"""Update the metadata of a metamessage
|
||||
|
||||
Args:
|
||||
metamessage (Metamessage): The metamessage to update
|
||||
metadata (dict): The new metadata for the metamessage
|
||||
|
||||
Returns:
|
||||
boolean: Whether the metamessage was successfully updated
|
||||
"""
|
||||
if metadata is None and metamessage_type is None:
|
||||
raise ValueError("metadata and metamessage_type cannot both be None")
|
||||
info = {"metamessage_type": metamessage_type, "metadata": metadata}
|
||||
url = f"{self.base_url}/metamessages/{metamessage.id}"
|
||||
response = await self.user.honcho.client.put(url, json=info)
|
||||
success = response.status_code < 400
|
||||
if metamessage_type is not None:
|
||||
metamessage.metamessage_type = metamessage_type
|
||||
if metadata is not None:
|
||||
metamessage.metadata = metadata
|
||||
return success
|
||||
|
||||
async def close(self):
|
||||
"""Closes a session by marking it as inactive"""
|
||||
url = f"{self.base_url}"
|
||||
|
|
@ -977,6 +1155,14 @@ class AsyncSession:
|
|||
response.raise_for_status()
|
||||
self._is_active = False
|
||||
|
||||
async def chat(self, query) -> str:
|
||||
url = f"{self.base_url}/chat"
|
||||
params = {"query": query}
|
||||
response = await self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return data["content"]
|
||||
|
||||
|
||||
class AsyncCollection:
|
||||
"""Represents a single collection for a user in an app"""
|
||||
|
|
@ -986,12 +1172,14 @@ class AsyncCollection:
|
|||
user: AsyncUser,
|
||||
id: uuid.UUID,
|
||||
name: str,
|
||||
metadata: dict,
|
||||
created_at: datetime.datetime,
|
||||
):
|
||||
"""Constructor for Collection"""
|
||||
self.user = user
|
||||
self.id: uuid.UUID = id
|
||||
self.name: str = name
|
||||
self.metadata: dict = metadata
|
||||
self.created_at: datetime.datetime = created_at
|
||||
|
||||
@property
|
||||
|
|
@ -1003,7 +1191,7 @@ class AsyncCollection:
|
|||
"""String representation of Collection"""
|
||||
return f"AsyncCollection(id={self.id}, name={self.name}, created_at={self.created_at})" # noqa: E501
|
||||
|
||||
async def update(self, name: str):
|
||||
async def update(self, name: Optional[str] = None, metadata: Optional[dict] = None):
|
||||
"""Update the name of the collection
|
||||
|
||||
Args:
|
||||
|
|
@ -1012,12 +1200,17 @@ class AsyncCollection:
|
|||
Returns:
|
||||
boolean: Whether the session was successfully updated
|
||||
"""
|
||||
info = {"name": name}
|
||||
if metadata is None and name is None:
|
||||
raise ValueError("metadata and name cannot both be None")
|
||||
info = {"name": name, "metadata": metadata}
|
||||
url = f"{self.base_url}"
|
||||
response = await self.user.honcho.client.put(url, json=info)
|
||||
response.raise_for_status()
|
||||
success = response.status_code < 400
|
||||
self.name = name
|
||||
if name is not None:
|
||||
self.name = name
|
||||
if metadata is not None:
|
||||
self.metadata = metadata
|
||||
return success
|
||||
|
||||
async def delete(self):
|
||||
|
|
@ -1075,7 +1268,11 @@ class AsyncCollection:
|
|||
)
|
||||
|
||||
async def get_documents(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
) -> AsyncGetDocumentPage:
|
||||
"""Get all documents for a collection
|
||||
|
||||
|
|
@ -1087,15 +1284,24 @@ class AsyncCollection:
|
|||
AsyncGetDocumentPage: Page of Document objects
|
||||
|
||||
"""
|
||||
url = (
|
||||
f"{self.base_url}/documents?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
)
|
||||
response = await self.user.honcho.client.get(url)
|
||||
# url = f"{self.base_url}/documents?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
url = f"{self.base_url}/documents"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = await self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return AsyncGetDocumentPage(data, self, reverse)
|
||||
return AsyncGetDocumentPage(data, self, filter, reverse)
|
||||
|
||||
async def get_documents_generator(self, reverse: bool = False):
|
||||
async def get_documents_generator(
|
||||
self, filter: Optional[dict] = None, reverse: bool = False
|
||||
):
|
||||
"""Shortcut Generator for get_documents. Generator to iterate through
|
||||
all documents for a collection in an app
|
||||
|
||||
|
|
@ -1105,7 +1311,7 @@ class AsyncCollection:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_documents_page = await self.get_documents(page, page_size, reverse)
|
||||
get_documents_page = await self.get_documents(filter, page, page_size, reverse)
|
||||
while True:
|
||||
for document in get_documents_page.items:
|
||||
yield document
|
||||
|
|
@ -1125,8 +1331,10 @@ class AsyncCollection:
|
|||
Returns:
|
||||
List[Document]: The response from the query with matching documents
|
||||
"""
|
||||
url = f"{self.base_url}/query?query={query}&top_k={top_k}"
|
||||
response = await self.user.honcho.client.get(url)
|
||||
# url = f"{self.base_url}/query?query={query}&top_k={top_k}"
|
||||
url = f"{self.base_url}/query"
|
||||
params = {"query": query, "top_k": top_k}
|
||||
response = await self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = [
|
||||
Document(
|
||||
|
|
@ -1141,7 +1349,10 @@ class AsyncCollection:
|
|||
return data
|
||||
|
||||
async def update_document(
|
||||
self, document: Document, content: Optional[str], metadata: Optional[dict]
|
||||
self,
|
||||
document: Document,
|
||||
content: Optional[str] = None,
|
||||
metadata: Optional[dict] = None,
|
||||
) -> Document:
|
||||
"""Update a document in the collection
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
import functools
|
||||
import importlib
|
||||
from typing import List
|
||||
|
||||
from honcho.schemas import Message
|
||||
|
||||
|
||||
def requires_langchain(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if importlib.util.find_spec("langchain") is None:
|
||||
raise ImportError("Langchain must be installed to use this feature")
|
||||
# raise RuntimeError("langchain is not installed")
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@requires_langchain
|
||||
def langchain_message_converter(messages: List[Message]):
|
||||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
|
||||
new_messages = []
|
||||
for message in messages:
|
||||
if message.is_user:
|
||||
new_messages.append(HumanMessage(content=message.content))
|
||||
else:
|
||||
new_messages.append(AIMessage(content=message.content))
|
||||
return new_messages
|
||||
|
|
@ -1,32 +1,60 @@
|
|||
import uuid
|
||||
import datetime
|
||||
|
||||
|
||||
class Message:
|
||||
def __init__(self, session_id: uuid.UUID, id: uuid.UUID, is_user: bool, content: str, created_at: datetime.datetime):
|
||||
def __init__(
|
||||
self,
|
||||
session_id: uuid.UUID,
|
||||
id: uuid.UUID,
|
||||
is_user: bool,
|
||||
content: str,
|
||||
metadata: dict,
|
||||
created_at: datetime.datetime,
|
||||
):
|
||||
"""Constructor for Message"""
|
||||
self.session_id = session_id
|
||||
self.id = id
|
||||
self.is_user = is_user
|
||||
self.content = content
|
||||
self.metadata = metadata
|
||||
self.created_at = created_at
|
||||
|
||||
def __str__(self):
|
||||
return f"Message(id={self.id}, is_user={self.is_user}, content={self.content})"
|
||||
|
||||
|
||||
class Metamessage:
|
||||
def __init__(self, id: uuid.UUID, message_id: uuid.UUID, metamessage_type: str, content: str, created_at: datetime.datetime):
|
||||
def __init__(
|
||||
self,
|
||||
id: uuid.UUID,
|
||||
message_id: uuid.UUID,
|
||||
metamessage_type: str,
|
||||
content: str,
|
||||
metadata: dict,
|
||||
created_at: datetime.datetime,
|
||||
):
|
||||
"""Constructor for Metamessage"""
|
||||
self.id = id
|
||||
self.message_id = message_id
|
||||
self.metamessage_type = metamessage_type
|
||||
self.content = content
|
||||
self.metadata = metadata
|
||||
self.created_at = created_at
|
||||
|
||||
def __str__(self):
|
||||
return f"Metamessage(id={self.id}, message_id={self.message_id}, metamessage_type={self.metamessage_type}, content={self.content})"
|
||||
|
||||
|
||||
|
||||
class Document:
|
||||
def __init__(self, id: uuid.UUID, collection_id: uuid.UUID, content: str, metadata: dict, created_at: datetime.datetime):
|
||||
def __init__(
|
||||
self,
|
||||
id: uuid.UUID,
|
||||
collection_id: uuid.UUID,
|
||||
content: str,
|
||||
metadata: dict,
|
||||
created_at: datetime.datetime,
|
||||
):
|
||||
"""Constructor for Document"""
|
||||
self.collection_id = collection_id
|
||||
self.id = id
|
||||
|
|
@ -36,4 +64,3 @@ class Document:
|
|||
|
||||
def __str__(self) -> str:
|
||||
return f"Document(id={self.id}, metadata={self.metadata}, content={self.content}, created_at={self.created_at})"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
|
|
@ -32,7 +33,13 @@ class GetPage:
|
|||
class GetUserPage(GetPage):
|
||||
"""Paginated Results for Get User Requests"""
|
||||
|
||||
def __init__(self, response: dict, honcho: Honcho, reverse: bool):
|
||||
def __init__(
|
||||
self,
|
||||
response: dict,
|
||||
honcho: Honcho,
|
||||
filter: Optional[dict],
|
||||
reverse: bool,
|
||||
):
|
||||
"""Constructor for Page Result from User Get Request
|
||||
|
||||
Args:
|
||||
|
|
@ -42,6 +49,7 @@ class GetUserPage(GetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.honcho = honcho
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
User(
|
||||
|
|
@ -57,7 +65,10 @@ class GetUserPage(GetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return self.honcho.get_users(
|
||||
page=(self.page + 1), page_size=self.page_size, reverse=self.reverse
|
||||
filter=self.filter,
|
||||
page=(self.page + 1),
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -70,6 +81,7 @@ class GetSessionPage(GetPage):
|
|||
user: User,
|
||||
reverse: bool,
|
||||
location_id: Optional[str],
|
||||
filter: Optional[dict],
|
||||
is_active: bool,
|
||||
):
|
||||
"""Constructor for Page Result from Session Get Request
|
||||
|
|
@ -85,6 +97,7 @@ class GetSessionPage(GetPage):
|
|||
self.location_id = location_id
|
||||
self.reverse = reverse
|
||||
self.is_active = is_active
|
||||
self.filter = filter
|
||||
self.items = [
|
||||
Session(
|
||||
user=user,
|
||||
|
|
@ -99,14 +112,15 @@ class GetSessionPage(GetPage):
|
|||
|
||||
def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
GetSessionPage | None: Next Page of Results or None if there
|
||||
are no more sessions to retreive from a query
|
||||
GetSessionPage | None: Next Page of Results or None if there are no more sessions to retreive from a query
|
||||
"""
|
||||
if self.page >= self.pages:
|
||||
return None
|
||||
return self.user.get_sessions(
|
||||
location_id=self.location_id,
|
||||
filter=self.filter,
|
||||
page=(self.page + 1),
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
|
|
@ -117,7 +131,13 @@ class GetSessionPage(GetPage):
|
|||
class GetMessagePage(GetPage):
|
||||
"""Paginated Results for Get Session Requests"""
|
||||
|
||||
def __init__(self, response: dict, session: Session, reverse: bool):
|
||||
def __init__(
|
||||
self,
|
||||
response: dict,
|
||||
session: Session,
|
||||
filter: Optional[dict],
|
||||
reverse: bool,
|
||||
):
|
||||
"""Constructor for Page Result from Session Get Request
|
||||
|
||||
Args:
|
||||
|
|
@ -127,6 +147,7 @@ class GetMessagePage(GetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.session = session
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Message(
|
||||
|
|
@ -134,6 +155,7 @@ class GetMessagePage(GetPage):
|
|||
id=message["id"],
|
||||
is_user=message["is_user"],
|
||||
content=message["content"],
|
||||
metadata=message["metadata"],
|
||||
created_at=message["created_at"],
|
||||
)
|
||||
for message in response["items"]
|
||||
|
|
@ -141,6 +163,7 @@ class GetMessagePage(GetPage):
|
|||
|
||||
def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
GetMessagePage | None: Next Page of Results or None if there
|
||||
are no more messages to retreive from a query
|
||||
|
|
@ -148,7 +171,7 @@ class GetMessagePage(GetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return self.session.get_messages(
|
||||
(self.page + 1), self.page_size, self.reverse
|
||||
self.filter, (self.page + 1), self.page_size, self.reverse
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -157,6 +180,7 @@ class GetMetamessagePage(GetPage):
|
|||
self,
|
||||
response: dict,
|
||||
session,
|
||||
filter: Optional[dict],
|
||||
reverse: bool,
|
||||
message_id: Optional[uuid.UUID],
|
||||
metamessage_type: Optional[str],
|
||||
|
|
@ -175,11 +199,13 @@ class GetMetamessagePage(GetPage):
|
|||
self.session = session
|
||||
self.message_id = message_id
|
||||
self.metamessage_type = metamessage_type
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Metamessage(
|
||||
id=metamessage["id"],
|
||||
message_id=metamessage["message_id"],
|
||||
metadata=metamessage["metadata"],
|
||||
metamessage_type=metamessage["metamessage_type"],
|
||||
content=metamessage["content"],
|
||||
created_at=metamessage["created_at"],
|
||||
|
|
@ -189,6 +215,7 @@ class GetMetamessagePage(GetPage):
|
|||
|
||||
def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
GetMetamessagePage | None: Next Page of Results or None if
|
||||
there are no more metamessages to retreive from a query
|
||||
|
|
@ -197,6 +224,7 @@ class GetMetamessagePage(GetPage):
|
|||
return None
|
||||
return self.session.get_metamessages(
|
||||
metamessage_type=self.metamessage_type,
|
||||
filter=self.filter,
|
||||
message=self.message_id,
|
||||
page=(self.page + 1),
|
||||
page_size=self.page_size,
|
||||
|
|
@ -207,7 +235,9 @@ class GetMetamessagePage(GetPage):
|
|||
class GetDocumentPage(GetPage):
|
||||
"""Paginated results for Get Document requests"""
|
||||
|
||||
def __init__(self, response: dict, collection, reverse: bool) -> None:
|
||||
def __init__(
|
||||
self, response: dict, collection, filter: Optional[dict], reverse: bool
|
||||
) -> None:
|
||||
"""Constructor for Page Result from Document Get Request
|
||||
|
||||
Args:
|
||||
|
|
@ -218,6 +248,7 @@ class GetDocumentPage(GetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.collection = collection
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Document(
|
||||
|
|
@ -232,6 +263,7 @@ class GetDocumentPage(GetPage):
|
|||
|
||||
def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
GetDocumentPage | None: Next Page of Results or None if there
|
||||
are no more sessions to retreive from a query
|
||||
|
|
@ -239,14 +271,19 @@ class GetDocumentPage(GetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return self.collection.get_documents(
|
||||
page=self.page + 1, page_size=self.page_size, reverse=self.reverse
|
||||
filter=self.filter,
|
||||
page=self.page + 1,
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
)
|
||||
|
||||
|
||||
class GetCollectionPage(GetPage):
|
||||
"""Paginated results for Get Collection requests"""
|
||||
|
||||
def __init__(self, response: dict, user: User, reverse: bool):
|
||||
def __init__(
|
||||
self, response: dict, user: User, filter: Optional[dict], reverse: bool
|
||||
):
|
||||
"""Constructor for page result from Get Collection Request
|
||||
|
||||
Args:
|
||||
|
|
@ -256,12 +293,14 @@ class GetCollectionPage(GetPage):
|
|||
"""
|
||||
super().__init__(response)
|
||||
self.user = user
|
||||
self.filter = filter
|
||||
self.reverse = reverse
|
||||
self.items = [
|
||||
Collection(
|
||||
user=user,
|
||||
id=collection["id"],
|
||||
name=collection["name"],
|
||||
metadata=collection["metadata"],
|
||||
created_at=collection["created_at"],
|
||||
)
|
||||
for collection in response["items"]
|
||||
|
|
@ -269,6 +308,7 @@ class GetCollectionPage(GetPage):
|
|||
|
||||
def next(self):
|
||||
"""Get the next page of results
|
||||
|
||||
Returns:
|
||||
GetCollectionPage | None: Next Page of Results or None if
|
||||
there are no more sessions to retreive from a query
|
||||
|
|
@ -276,6 +316,7 @@ class GetCollectionPage(GetPage):
|
|||
if self.page >= self.pages:
|
||||
return None
|
||||
return self.user.get_collections(
|
||||
filter=self.filter,
|
||||
page=self.page + 1,
|
||||
page_size=self.page_size,
|
||||
reverse=self.reverse,
|
||||
|
|
@ -390,7 +431,11 @@ class Honcho:
|
|||
)
|
||||
|
||||
def get_users(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Get Paginated list of users
|
||||
|
||||
|
|
@ -402,14 +447,24 @@ class Honcho:
|
|||
Returns:
|
||||
GetUserPage: Paginated list of users
|
||||
"""
|
||||
url = f"{self.base_url}/users?page={page}&size={page_size}&reverse={reverse}"
|
||||
response = self.client.get(url)
|
||||
# url = f"{self.base_url}/users?page={page}&size={page_size}&reverse={reverse}"
|
||||
url = f"{self.base_url}/users"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = self.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return GetUserPage(data, self, reverse)
|
||||
return GetUserPage(data, self, filter, reverse)
|
||||
|
||||
def get_users_generator(
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Shortcut Generator for get_users. Generator to iterate through
|
||||
|
|
@ -424,7 +479,7 @@ class Honcho:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_user_response = self.get_users(page, page_size, reverse)
|
||||
get_user_response = self.get_users(filter, page, page_size, reverse)
|
||||
while True:
|
||||
for session in get_user_response.items:
|
||||
yield session
|
||||
|
|
@ -523,6 +578,7 @@ class User:
|
|||
def get_sessions(
|
||||
self,
|
||||
location_id: Optional[str] = None,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
|
|
@ -542,20 +598,33 @@ class User:
|
|||
GetSessionPage: Page or results for get_sessions query
|
||||
|
||||
"""
|
||||
url = (
|
||||
f"{self.base_url}/sessions?page={page}&size={page_size}&reverse={reverse}&is_active={is_active}"
|
||||
+ (f"&location_id={location_id}" if location_id else "")
|
||||
)
|
||||
response = self.honcho.client.get(url)
|
||||
# url = (
|
||||
# f"{self.base_url}/sessions?page={page}&size={page_size}&reverse={reverse}&is_active={is_active}"
|
||||
# + (f"&location_id={location_id}" if location_id else "")
|
||||
# )
|
||||
url = f"{self.base_url}/sessions"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
"is_active": is_active,
|
||||
}
|
||||
if location_id:
|
||||
params["location_id"] = location_id
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = self.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return GetSessionPage(data, self, reverse, location_id, is_active)
|
||||
return GetSessionPage(data, self, reverse, location_id, filter, is_active)
|
||||
|
||||
def get_sessions_generator(
|
||||
self,
|
||||
location_id: Optional[str] = None,
|
||||
reverse: bool = False,
|
||||
is_active: bool = False,
|
||||
filter: Optional[dict] = None,
|
||||
):
|
||||
"""Shortcut Generator for get_sessions. Generator to iterate through
|
||||
all sessions for a user in an app
|
||||
|
|
@ -573,7 +642,7 @@ class User:
|
|||
page = 1
|
||||
page_size = 50
|
||||
get_session_response = self.get_sessions(
|
||||
location_id, page, page_size, reverse, is_active
|
||||
location_id, filter, page, page_size, reverse, is_active
|
||||
)
|
||||
while True:
|
||||
for session in get_session_response.items:
|
||||
|
|
@ -618,6 +687,7 @@ class User:
|
|||
def create_collection(
|
||||
self,
|
||||
name: str,
|
||||
metadata: Optional[dict] = None,
|
||||
):
|
||||
"""Create a collection for a user
|
||||
|
||||
|
|
@ -628,7 +698,9 @@ class User:
|
|||
Collection: The Collection object of the new Collection
|
||||
|
||||
"""
|
||||
data = {"name": name}
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
data = {"name": name, "metadata": metadata}
|
||||
url = f"{self.base_url}/collections"
|
||||
response = self.honcho.client.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
|
|
@ -637,6 +709,7 @@ class User:
|
|||
self,
|
||||
id=data["id"],
|
||||
name=name,
|
||||
metadata=metadata,
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -658,11 +731,16 @@ class User:
|
|||
user=self,
|
||||
id=data["id"],
|
||||
name=data["name"],
|
||||
metadata=data["metadata"],
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
def get_collections(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Return collections associated with a user paginated
|
||||
|
||||
|
|
@ -675,13 +753,24 @@ class User:
|
|||
GetCollectionPage: Page or results for get_collections query
|
||||
|
||||
"""
|
||||
url = f"{self.base_url}/collections?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
response = self.honcho.client.get(url)
|
||||
# url = f"{self.base_url}/collections?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
url = f"{self.base_url}/collections"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = self.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return GetCollectionPage(data, self, reverse)
|
||||
return GetCollectionPage(data, self, filter, reverse)
|
||||
|
||||
def get_collections_generator(self, reverse: bool = False):
|
||||
def get_collections_generator(
|
||||
self, filter: Optional[dict] = None, reverse: bool = False
|
||||
):
|
||||
"""Shortcut Generator for get_sessions. Generator to iterate through
|
||||
all sessions for a user in an app
|
||||
|
||||
|
|
@ -694,7 +783,9 @@ class User:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_collection_response = self.get_collections(page, page_size, reverse)
|
||||
get_collection_response = self.get_collections(
|
||||
filter, page, page_size, reverse
|
||||
)
|
||||
while True:
|
||||
for collection in get_collection_response.items:
|
||||
yield collection
|
||||
|
|
@ -740,7 +831,9 @@ class Session:
|
|||
"""Returns whether the session is active - made property to prevent tampering"""
|
||||
return self._is_active
|
||||
|
||||
def create_message(self, is_user: bool, content: str):
|
||||
def create_message(
|
||||
self, is_user: bool, content: str, metadata: Optional[dict] = None
|
||||
):
|
||||
"""Adds a message to the session
|
||||
|
||||
Args:
|
||||
|
|
@ -753,7 +846,9 @@ class Session:
|
|||
"""
|
||||
if not self.is_active:
|
||||
raise Exception("Session is inactive")
|
||||
data = {"is_user": is_user, "content": content}
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
data = {"is_user": is_user, "content": content, "metadata": metadata}
|
||||
url = f"{self.base_url}/messages"
|
||||
response = self.user.honcho.client.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
|
|
@ -763,6 +858,7 @@ class Session:
|
|||
id=data["id"],
|
||||
is_user=is_user,
|
||||
content=content,
|
||||
metadata=metadata,
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -785,11 +881,16 @@ class Session:
|
|||
id=data["id"],
|
||||
is_user=data["is_user"],
|
||||
content=data["content"],
|
||||
metadata=data["metadata"],
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
def get_messages(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
) -> GetMessagePage:
|
||||
"""Get all messages for a session
|
||||
|
||||
|
|
@ -802,13 +903,23 @@ class Session:
|
|||
GetMessagePage: Page of Message objects
|
||||
|
||||
"""
|
||||
url = f"{self.base_url}/messages?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
response = self.user.honcho.client.get(url)
|
||||
url = f"{self.base_url}/messages"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return GetMessagePage(data, self, reverse)
|
||||
return GetMessagePage(data, self, filter, reverse)
|
||||
|
||||
def get_messages_generator(self, reverse: bool = False):
|
||||
def get_messages_generator(
|
||||
self, filter: Optional[dict] = None, reverse: bool = False
|
||||
):
|
||||
"""Shortcut Generator for get_messages. Generator to iterate through
|
||||
all messages for a session in an app
|
||||
|
||||
|
|
@ -818,7 +929,7 @@ class Session:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_messages_page = self.get_messages(page, page_size, reverse)
|
||||
get_messages_page = self.get_messages(filter, page, page_size, reverse)
|
||||
while True:
|
||||
for message in get_messages_page.items:
|
||||
yield message
|
||||
|
|
@ -830,7 +941,11 @@ class Session:
|
|||
get_messages_page = new_messages
|
||||
|
||||
def create_metamessage(
|
||||
self, message: Message, metamessage_type: str, content: str
|
||||
self,
|
||||
message: Message,
|
||||
metamessage_type: str,
|
||||
content: str,
|
||||
metadata: Optional[dict] = None,
|
||||
):
|
||||
"""Adds a metamessage to a session and links it to a specific message
|
||||
|
||||
|
|
@ -845,10 +960,13 @@ class Session:
|
|||
"""
|
||||
if not self.is_active:
|
||||
raise Exception("Session is inactive")
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
data = {
|
||||
"metamessage_type": metamessage_type,
|
||||
"content": content,
|
||||
"message_id": message.id,
|
||||
"metadata": metadata,
|
||||
}
|
||||
url = f"{self.base_url}/metamessages"
|
||||
response = self.user.honcho.client.post(url, json=data)
|
||||
|
|
@ -859,6 +977,7 @@ class Session:
|
|||
message_id=message.id,
|
||||
metamessage_type=metamessage_type,
|
||||
content=content,
|
||||
metadata=metadata,
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -881,6 +1000,7 @@ class Session:
|
|||
message_id=data["message_id"],
|
||||
metamessage_type=data["metamessage_type"],
|
||||
content=data["content"],
|
||||
metadata=data["metadata"],
|
||||
created_at=data["created_at"],
|
||||
)
|
||||
|
||||
|
|
@ -888,6 +1008,7 @@ class Session:
|
|||
self,
|
||||
metamessage_type: Optional[str] = None,
|
||||
message: Optional[Message] = None,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
|
|
@ -905,23 +1026,35 @@ class Session:
|
|||
list[dict]: List of Message objects
|
||||
|
||||
"""
|
||||
url = f"{self.base_url}/metamessages?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
# url = f"{self.base_url}/metamessages?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
url = f"{self.base_url}/metamessages"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if metamessage_type:
|
||||
url += f"&metamessage_type={metamessage_type}"
|
||||
# url += f"&metamessage_type={metamessage_type}"
|
||||
params["metamessage_type"] = metamessage_type
|
||||
if message:
|
||||
url += f"&message_id={message.id}"
|
||||
response = self.user.honcho.client.get(url)
|
||||
# url += f"&message_id={message.id}"
|
||||
params["message_id"] = message.id
|
||||
if filter is not None:
|
||||
json_metadata = json.dumps(filter)
|
||||
params["filter"] = json_metadata
|
||||
response = self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
message_id = message.id if message else None
|
||||
return GetMetamessagePage(
|
||||
data, self, reverse, message_id, metamessage_type
|
||||
data, self, filter, reverse, message_id, metamessage_type
|
||||
)
|
||||
|
||||
def get_metamessages_generator(
|
||||
self,
|
||||
metamessage_type: Optional[str] = None,
|
||||
message: Optional[Message] = None,
|
||||
filter: Optional[dict] = None,
|
||||
reverse: bool = False,
|
||||
):
|
||||
"""Shortcut Generator for get_metamessages. Generator to iterate
|
||||
|
|
@ -940,6 +1073,7 @@ class Session:
|
|||
get_metamessages_page = self.get_metamessages(
|
||||
metamessage_type=metamessage_type,
|
||||
message=message,
|
||||
filter=filter,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
reverse=reverse,
|
||||
|
|
@ -970,6 +1104,50 @@ class Session:
|
|||
self.metadata = metadata
|
||||
return success
|
||||
|
||||
def update_message(self, message: Message, metadata: dict):
|
||||
"""Update the metadata of a message
|
||||
|
||||
Args:
|
||||
message (Message): The message to update
|
||||
metadata (dict): The new metadata for the message
|
||||
|
||||
Returns:
|
||||
boolean: Whether the message was successfully updated
|
||||
"""
|
||||
info = {"metadata": metadata}
|
||||
url = f"{self.base_url}/messages/{message.id}"
|
||||
response = self.user.honcho.client.put(url, json=info)
|
||||
success = response.status_code < 400
|
||||
message.metadata = metadata
|
||||
return success
|
||||
|
||||
def update_metamessage(
|
||||
self,
|
||||
metamessage: Metamessage,
|
||||
metamessage_type: Optional[str],
|
||||
metadata: Optional[dict],
|
||||
):
|
||||
"""Update the metadata of a metamessage
|
||||
|
||||
Args:
|
||||
metamessage (Metamessage): The metamessage to update
|
||||
metadata (dict): The new metadata for the metamessage
|
||||
|
||||
Returns:
|
||||
boolean: Whether the metamessage was successfully updated
|
||||
"""
|
||||
if metadata is None and metamessage_type is None:
|
||||
raise ValueError("metadata and metamessage_type cannot both be None")
|
||||
info = {"metamessage_type": metamessage_type, "metadata": metadata}
|
||||
url = f"{self.base_url}/metamessages/{metamessage.id}"
|
||||
response = self.user.honcho.client.put(url, json=info)
|
||||
success = response.status_code < 400
|
||||
if metamessage_type is not None:
|
||||
metamessage.metamessage_type = metamessage_type
|
||||
if metadata is not None:
|
||||
metamessage.metadata = metadata
|
||||
return success
|
||||
|
||||
def close(self):
|
||||
"""Closes a session by marking it as inactive"""
|
||||
url = f"{self.base_url}"
|
||||
|
|
@ -977,6 +1155,14 @@ class Session:
|
|||
response.raise_for_status()
|
||||
self._is_active = False
|
||||
|
||||
def chat(self, query) -> str:
|
||||
url = f"{self.base_url}/chat"
|
||||
params = {"query": query}
|
||||
response = self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return data["content"]
|
||||
|
||||
|
||||
class Collection:
|
||||
"""Represents a single collection for a user in an app"""
|
||||
|
|
@ -986,12 +1172,14 @@ class Collection:
|
|||
user: User,
|
||||
id: uuid.UUID,
|
||||
name: str,
|
||||
metadata: dict,
|
||||
created_at: datetime.datetime,
|
||||
):
|
||||
"""Constructor for Collection"""
|
||||
self.user = user
|
||||
self.id: uuid.UUID = id
|
||||
self.name: str = name
|
||||
self.metadata: dict = metadata
|
||||
self.created_at: datetime.datetime = created_at
|
||||
|
||||
@property
|
||||
|
|
@ -1003,7 +1191,7 @@ class Collection:
|
|||
"""String representation of Collection"""
|
||||
return f"Collection(id={self.id}, name={self.name}, created_at={self.created_at})" # noqa: E501
|
||||
|
||||
def update(self, name: str):
|
||||
def update(self, name: Optional[str] = None, metadata: Optional[dict] = None):
|
||||
"""Update the name of the collection
|
||||
|
||||
Args:
|
||||
|
|
@ -1012,12 +1200,17 @@ class Collection:
|
|||
Returns:
|
||||
boolean: Whether the session was successfully updated
|
||||
"""
|
||||
info = {"name": name}
|
||||
if metadata is None and name is None:
|
||||
raise ValueError("metadata and name cannot both be None")
|
||||
info = {"name": name, "metadata": metadata}
|
||||
url = f"{self.base_url}"
|
||||
response = self.user.honcho.client.put(url, json=info)
|
||||
response.raise_for_status()
|
||||
success = response.status_code < 400
|
||||
self.name = name
|
||||
if name is not None:
|
||||
self.name = name
|
||||
if metadata is not None:
|
||||
self.metadata = metadata
|
||||
return success
|
||||
|
||||
def delete(self):
|
||||
|
|
@ -1075,7 +1268,11 @@ class Collection:
|
|||
)
|
||||
|
||||
def get_documents(
|
||||
self, page: int = 1, page_size: int = 50, reverse: bool = False
|
||||
self,
|
||||
filter: Optional[dict] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
reverse: bool = False,
|
||||
) -> GetDocumentPage:
|
||||
"""Get all documents for a collection
|
||||
|
||||
|
|
@ -1087,15 +1284,24 @@ class Collection:
|
|||
GetDocumentPage: Page of Document objects
|
||||
|
||||
"""
|
||||
url = (
|
||||
f"{self.base_url}/documents?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
)
|
||||
response = self.user.honcho.client.get(url)
|
||||
# url = f"{self.base_url}/documents?page={page}&size={page_size}&reverse={reverse}" # noqa: E501
|
||||
url = f"{self.base_url}/documents"
|
||||
params = {
|
||||
"page": page,
|
||||
"size": page_size,
|
||||
"reverse": reverse,
|
||||
}
|
||||
if filter is not None:
|
||||
json_filter = json.dumps(filter)
|
||||
params["filter"] = json_filter
|
||||
response = self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return GetDocumentPage(data, self, reverse)
|
||||
return GetDocumentPage(data, self, filter, reverse)
|
||||
|
||||
def get_documents_generator(self, reverse: bool = False):
|
||||
def get_documents_generator(
|
||||
self, filter: Optional[dict] = None, reverse: bool = False
|
||||
):
|
||||
"""Shortcut Generator for get_documents. Generator to iterate through
|
||||
all documents for a collection in an app
|
||||
|
||||
|
|
@ -1105,7 +1311,7 @@ class Collection:
|
|||
"""
|
||||
page = 1
|
||||
page_size = 50
|
||||
get_documents_page = self.get_documents(page, page_size, reverse)
|
||||
get_documents_page = self.get_documents(filter, page, page_size, reverse)
|
||||
while True:
|
||||
for document in get_documents_page.items:
|
||||
yield document
|
||||
|
|
@ -1125,8 +1331,10 @@ class Collection:
|
|||
Returns:
|
||||
List[Document]: The response from the query with matching documents
|
||||
"""
|
||||
url = f"{self.base_url}/query?query={query}&top_k={top_k}"
|
||||
response = self.user.honcho.client.get(url)
|
||||
# url = f"{self.base_url}/query?query={query}&top_k={top_k}"
|
||||
url = f"{self.base_url}/query"
|
||||
params = {"query": query, "top_k": top_k}
|
||||
response = self.user.honcho.client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
data = [
|
||||
Document(
|
||||
|
|
@ -1141,7 +1349,10 @@ class Collection:
|
|||
return data
|
||||
|
||||
def update_document(
|
||||
self, document: Document, content: Optional[str], metadata: Optional[dict]
|
||||
self,
|
||||
document: Document,
|
||||
content: Optional[str] = None,
|
||||
metadata: Optional[dict] = None,
|
||||
) -> Document:
|
||||
"""Update a document in the collection
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,27 @@
|
|||
# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
version = "0.7.16"
|
||||
description = "A light, configurable Sphinx theme"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"},
|
||||
{file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.2.0"
|
||||
version = "4.3.0"
|
||||
description = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"},
|
||||
{file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"},
|
||||
{file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"},
|
||||
{file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -23,16 +35,153 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin
|
|||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
||||
trio = ["trio (>=0.23)"]
|
||||
|
||||
[[package]]
|
||||
name = "babel"
|
||||
version = "2.14.0"
|
||||
description = "Internationalization utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"},
|
||||
{file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "beautifulsoup4"
|
||||
version = "4.12.3"
|
||||
description = "Screen-scraping library"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
files = [
|
||||
{file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"},
|
||||
{file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
soupsieve = ">1.2"
|
||||
|
||||
[package.extras]
|
||||
cchardet = ["cchardet"]
|
||||
chardet = ["chardet"]
|
||||
charset-normalizer = ["charset-normalizer"]
|
||||
html5lib = ["html5lib"]
|
||||
lxml = ["lxml"]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2023.11.17"
|
||||
version = "2024.2.2"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"},
|
||||
{file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
|
||||
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
|
||||
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.3.2"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
|
||||
{file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -47,6 +196,83 @@ files = [
|
|||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.4.3"
|
||||
description = "Code coverage measurement for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"},
|
||||
{file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"},
|
||||
{file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"},
|
||||
{file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"},
|
||||
{file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"},
|
||||
{file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"},
|
||||
{file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"},
|
||||
{file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
toml = ["tomli"]
|
||||
|
||||
[[package]]
|
||||
name = "docutils"
|
||||
version = "0.20.1"
|
||||
description = "Docutils -- Python Documentation Utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"},
|
||||
{file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.0"
|
||||
|
|
@ -62,6 +288,24 @@ files = [
|
|||
[package.extras]
|
||||
test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "furo"
|
||||
version = "2024.1.29"
|
||||
description = "A clean customisable Sphinx documentation theme."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "furo-2024.1.29-py3-none-any.whl", hash = "sha256:3548be2cef45a32f8cdc0272d415fcb3e5fa6a0eb4ddfe21df3ecf1fe45a13cf"},
|
||||
{file = "furo-2024.1.29.tar.gz", hash = "sha256:4d6b2fe3f10a6e36eb9cc24c1e7beb38d7a23fc7b3c382867503b7fcac8a1e02"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
beautifulsoup4 = "*"
|
||||
pygments = ">=2.7"
|
||||
sphinx = ">=6.0,<8.0"
|
||||
sphinx-basic-ng = "*"
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.14.0"
|
||||
|
|
@ -76,14 +320,14 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.2"
|
||||
version = "1.0.4"
|
||||
description = "A minimal low-level HTTP client."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"},
|
||||
{file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"},
|
||||
{file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"},
|
||||
{file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -94,7 +338,7 @@ h11 = ">=0.13,<0.15"
|
|||
asyncio = ["anyio (>=4.0,<5.0)"]
|
||||
http2 = ["h2 (>=3,<5)"]
|
||||
socks = ["socksio (>=1.0.0,<2.0.0)"]
|
||||
trio = ["trio (>=0.22.0,<0.23.0)"]
|
||||
trio = ["trio (>=0.22.0,<0.25.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
|
|
@ -133,6 +377,38 @@ files = [
|
|||
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imagesize"
|
||||
version = "1.4.1"
|
||||
description = "Getting image size from png/jpeg/jpeg2000/gif file"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
files = [
|
||||
{file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
|
||||
{file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "7.0.2"
|
||||
description = "Read metadata from Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"},
|
||||
{file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
zipp = ">=0.5"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
perf = ["ipython"]
|
||||
testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
|
|
@ -145,34 +421,138 @@ files = [
|
|||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.3"
|
||||
description = "A very fast and expressive template engine."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
|
||||
{file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.0"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "2.1.5"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
|
||||
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
|
||||
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
|
||||
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
|
||||
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
|
||||
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
|
||||
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
|
||||
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
version = "24.0"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
{file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
|
||||
{file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
|
||||
{file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
|
||||
{file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
|
||||
{file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.17.2"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"},
|
||||
{file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
plugins = ["importlib-metadata"]
|
||||
windows-terminal = ["colorama (>=0.4.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "7.4.4"
|
||||
|
|
@ -198,35 +578,235 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no
|
|||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.23.4"
|
||||
version = "0.23.5.post1"
|
||||
description = "Pytest support for asyncio"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-asyncio-0.23.4.tar.gz", hash = "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2"},
|
||||
{file = "pytest_asyncio-0.23.4-py3-none-any.whl", hash = "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef"},
|
||||
{file = "pytest-asyncio-0.23.5.post1.tar.gz", hash = "sha256:b9a8806bea78c21276bc34321bbf234ba1b2ea5b30d9f0ce0f2dea45e4685813"},
|
||||
{file = "pytest_asyncio-0.23.5.post1-py3-none-any.whl", hash = "sha256:30f54d27774e79ac409778889880242b0403d09cabd65b727ce90fe92dd5d80e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=7.0.0,<8"
|
||||
pytest = ">=7.0.0,<9"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
|
||||
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.31.0"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
|
||||
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
charset-normalizer = ">=2,<4"
|
||||
idna = ">=2.5,<4"
|
||||
urllib3 = ">=1.21.1,<3"
|
||||
|
||||
[package.extras]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.0"
|
||||
version = "1.3.1"
|
||||
description = "Sniff out which async library your code is running under"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
|
||||
{file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
|
||||
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
||||
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snowballstemmer"
|
||||
version = "2.2.0"
|
||||
description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
|
||||
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "soupsieve"
|
||||
version = "2.5"
|
||||
description = "A modern CSS selector implementation for Beautiful Soup."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"},
|
||||
{file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx"
|
||||
version = "7.2.6"
|
||||
description = "Python documentation generator"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"},
|
||||
{file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
alabaster = ">=0.7,<0.8"
|
||||
babel = ">=2.9"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
docutils = ">=0.18.1,<0.21"
|
||||
imagesize = ">=1.3"
|
||||
importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""}
|
||||
Jinja2 = ">=3.0"
|
||||
packaging = ">=21.0"
|
||||
Pygments = ">=2.14"
|
||||
requests = ">=2.25.0"
|
||||
snowballstemmer = ">=2.0"
|
||||
sphinxcontrib-applehelp = "*"
|
||||
sphinxcontrib-devhelp = "*"
|
||||
sphinxcontrib-htmlhelp = ">=2.0.0"
|
||||
sphinxcontrib-jsmath = "*"
|
||||
sphinxcontrib-qthelp = "*"
|
||||
sphinxcontrib-serializinghtml = ">=1.1.9"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinxcontrib-websupport"]
|
||||
lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"]
|
||||
test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx-basic-ng"
|
||||
version = "1.0.0b2"
|
||||
description = "A modern skeleton for Sphinx themes."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"},
|
||||
{file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
sphinx = ">=4.0"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-applehelp"
|
||||
version = "1.0.8"
|
||||
description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"},
|
||||
{file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
lint = ["docutils-stubs", "flake8", "mypy"]
|
||||
standalone = ["Sphinx (>=5)"]
|
||||
test = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-devhelp"
|
||||
version = "1.0.6"
|
||||
description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"},
|
||||
{file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
lint = ["docutils-stubs", "flake8", "mypy"]
|
||||
standalone = ["Sphinx (>=5)"]
|
||||
test = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-htmlhelp"
|
||||
version = "2.0.5"
|
||||
description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"},
|
||||
{file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
lint = ["docutils-stubs", "flake8", "mypy"]
|
||||
standalone = ["Sphinx (>=5)"]
|
||||
test = ["html5lib", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-jsmath"
|
||||
version = "1.0.1"
|
||||
description = "A sphinx extension which renders display math in HTML via JavaScript"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
|
||||
{file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
test = ["flake8", "mypy", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-qthelp"
|
||||
version = "1.0.7"
|
||||
description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"},
|
||||
{file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
lint = ["docutils-stubs", "flake8", "mypy"]
|
||||
standalone = ["Sphinx (>=5)"]
|
||||
test = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-serializinghtml"
|
||||
version = "1.1.10"
|
||||
description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"},
|
||||
{file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
lint = ["docutils-stubs", "flake8", "mypy"]
|
||||
standalone = ["Sphinx (>=5)"]
|
||||
test = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
|
|
@ -241,17 +821,51 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.9.0"
|
||||
version = "4.10.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
|
||||
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
||||
{file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
|
||||
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.1"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
|
||||
{file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
h2 = ["h2 (>=4,<5)"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.18.0"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "zipp-3.18.0-py3-none-any.whl", hash = "sha256:c1bb803ed69d2cce2373152797064f7e79bc43f0a3748eb494096a867e0ebf79"},
|
||||
{file = "zipp-3.18.0.tar.gz", hash = "sha256:df8d042b02765029a09b157efd8e820451045890acc30f8e37dd2f94a060221f"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "6ccea662fa5a5bae88618123d5d05e0d4955c234b7e1a688d2fae2f90cd9f7f8"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "bf46c7a976758553f5f41e0d73766388e5b93ccf383d7870106286c5c570cedf"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "honcho-ai"
|
||||
version = "0.0.4"
|
||||
version = "0.0.5"
|
||||
description = "Python Client SDK for Honcho"
|
||||
authors = ["Plastic Labs <hello@plasticlabs.ai>"]
|
||||
license = "AGPL-3.0"
|
||||
|
|
@ -8,12 +8,17 @@ readme = "README.md"
|
|||
packages = [{include = "honcho"}]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
python = "^3.9"
|
||||
httpx = "^0.26.0"
|
||||
|
||||
[tool.poetry.group.test.dependencies]
|
||||
pytest = "^7.4.4"
|
||||
pytest-asyncio = "^0.23.4"
|
||||
coverage = "^7.4.3"
|
||||
|
||||
[tool.poetry.group.docs.dependencies]
|
||||
sphinx = "^7.2.6"
|
||||
furo = "^2024.1.29"
|
||||
|
||||
[tool.ruff.lint]
|
||||
# from https://docs.astral.sh/ruff/linter/#rule-selection example
|
||||
|
|
|
|||
|
|
@ -15,6 +15,45 @@ from honcho import (
|
|||
from honcho import AsyncHoncho as Honcho
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_session_metadata_filter():
|
||||
app_name = str(uuid1())
|
||||
user_name = str(uuid1())
|
||||
honcho = Honcho(app_name, "http://localhost:8000")
|
||||
await honcho.initialize()
|
||||
user = await honcho.create_user(user_name)
|
||||
await user.create_session()
|
||||
await user.create_session(metadata={"foo": "bar"})
|
||||
await user.create_session(metadata={"foo": "bar"})
|
||||
|
||||
response = await user.get_sessions(filter={"foo": "bar"})
|
||||
retrieved_sessions = response.items
|
||||
|
||||
assert len(retrieved_sessions) == 2
|
||||
|
||||
response = await user.get_sessions()
|
||||
|
||||
assert len(response.items) == 3
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_delete_session_metadata():
|
||||
app_name = str(uuid1())
|
||||
user_name = str(uuid1())
|
||||
honcho = Honcho(app_name, "http://localhost:8000")
|
||||
await honcho.initialize()
|
||||
user = await honcho.create_user(user_name)
|
||||
retrieved_session = await user.create_session(metadata={"foo": "bar"})
|
||||
|
||||
assert retrieved_session.metadata == {"foo": "bar"}
|
||||
|
||||
await retrieved_session.update(metadata={})
|
||||
|
||||
session_copy = await user.get_session(retrieved_session.id)
|
||||
|
||||
assert session_copy.metadata == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_update():
|
||||
user_name = str(uuid1())
|
||||
|
|
|
|||
|
|
@ -15,6 +15,43 @@ from honcho import (
|
|||
from honcho import Honcho as Honcho
|
||||
|
||||
|
||||
def test_session_metadata_filter():
|
||||
app_name = str(uuid1())
|
||||
user_name = str(uuid1())
|
||||
honcho = Honcho(app_name, "http://localhost:8000")
|
||||
honcho.initialize()
|
||||
user = honcho.create_user(user_name)
|
||||
user.create_session()
|
||||
user.create_session(metadata={"foo": "bar"})
|
||||
user.create_session(metadata={"foo": "bar"})
|
||||
|
||||
response = user.get_sessions(filter={"foo": "bar"})
|
||||
retrieved_sessions = response.items
|
||||
|
||||
assert len(retrieved_sessions) == 2
|
||||
|
||||
response = user.get_sessions()
|
||||
|
||||
assert len(response.items) == 3
|
||||
|
||||
|
||||
def test_delete_session_metadata():
|
||||
app_name = str(uuid1())
|
||||
user_name = str(uuid1())
|
||||
honcho = Honcho(app_name, "http://localhost:8000")
|
||||
honcho.initialize()
|
||||
user = honcho.create_user(user_name)
|
||||
retrieved_session = user.create_session(metadata={"foo": "bar"})
|
||||
|
||||
assert retrieved_session.metadata == {"foo": "bar"}
|
||||
|
||||
retrieved_session.update(metadata={})
|
||||
|
||||
session_copy = user.get_session(retrieved_session.id)
|
||||
|
||||
assert session_copy.metadata == {}
|
||||
|
||||
|
||||
def test_user_update():
|
||||
user_name = str(uuid1())
|
||||
app_name = str(uuid1())
|
||||
|
|
|
|||
Loading…
Reference in New Issue