Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support python 3.11 and fix sqlite initialisation issues #168

Merged
merged 9 commits into from
Feb 21, 2025
13 changes: 11 additions & 2 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ build-backend = "hatchling.build"

[project]
name = "pyspur"
version = "0.1.4"
version = "0.1.5"
description = "PySpur is a Graph UI for building AI Agents in Python"
requires-python = ">=3.12"
requires-python = ">=3.11"
license = "Apache-2.0"
classifiers = [
"Operating System :: MacOS :: MacOS X",
"Operating System :: POSIX :: Linux",
"Operating System :: Unix",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
maintainers = [
{name = "Srijan Patel", email = "srijan@pyspur.dev"},
{name = "Jean Kaddour", email = "jean@pyspur.dev"},
Expand Down
9 changes: 5 additions & 4 deletions backend/pyspur/api/main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from dotenv import load_dotenv
import tempfile
import shutil
import tempfile
from contextlib import ExitStack, asynccontextmanager
from importlib.resources import files, as_file
from importlib.resources import as_file, files
from pathlib import Path

from dotenv import load_dotenv
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pathlib import Path

from .api_app import api_app

Expand Down
11 changes: 8 additions & 3 deletions backend/pyspur/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,14 @@ def init(
print("[green]✓[/green] Created .env from template")

# add PROJECT_ROOT to .env
with open(env_path, "a") as f:
f.write("""\nDO NOT CHANGE THIS VALUE\n""")
f.write("\nPROJECT_ROOT=" + str(target_dir) + "\n")
# Check if PROJECT_ROOT is already defined in .env
with open(env_path, "r") as f:
if "PROJECT_ROOT=" not in f.read():
with open(env_path, "a") as f:
f.write("\n# ================================")
f.write("\n# PROJECT_ROOT: DO NOT CHANGE THIS VALUE")
f.write("\n# ================================")
f.write("\nPROJECT_ROOT=" + str(target_dir) + "\n")

# Create a data directory
data_dir = target_dir / "data"
Expand Down
38 changes: 31 additions & 7 deletions backend/pyspur/cli/utils.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"""Utility functions for the PySpur CLI."""

from pathlib import Path
import shutil
from importlib import resources
import tempfile
from importlib import resources
from pathlib import Path

from rich import print
import typer
from dotenv import load_dotenv
from sqlalchemy import text
from alembic import command
from alembic.config import Config
from alembic.runtime.migration import MigrationContext
from dotenv import load_dotenv
from rich import print
from sqlalchemy import text


def copy_template_file(template_name: str, dest_path: Path) -> None:
Expand Down Expand Up @@ -39,9 +39,24 @@ def load_environment() -> None:
def run_migrations() -> None:
"""Run database migrations using SQLAlchemy."""
try:
from ..database import engine, database_url
# ruff: noqa: F401
from ..database import database_url, engine
from ..models.base_model import BaseModel

# Import models
from ..models.dataset_model import DatasetModel # type: ignore
from ..models.dc_and_vi_model import (
DocumentCollectionModel, # type: ignore
VectorIndexModel, # type: ignore
)
from ..models.eval_run_model import EvalRunModel # type: ignore
from ..models.output_file_model import OutputFileModel # type: ignore
from ..models.run_model import RunModel # type: ignore
from ..models.task_model import TaskModel # type: ignore
from ..models.workflow_model import WorkflowModel # type: ignore
from ..models.workflow_version_model import WorkflowVersionModel # type: ignore
# Import all models to ensure they're registered with SQLAlchemy

# Test connection
with engine.connect() as conn:
conn.execute(text("SELECT 1"))
Expand All @@ -51,10 +66,19 @@ def run_migrations() -> None:
if database_url.startswith("sqlite"):
try:
BaseModel.metadata.create_all(engine)
print("[green]✓[/green] Created SQLite database")
print(f"[green]✓[/green] Database URL: {database_url}")
# Print all tables in the database
tables = BaseModel.metadata.tables
if tables:
print("\n[green]✓[/green] Successfully initialized SQLite database")
else:
print("[red]![/red] SQLite database is empty")
raise typer.Exit(1)
print("[yellow]![/yellow] SQLite database is not recommended for production")
print("[yellow]![/yellow] Please use a postgres instance instead")
return
except Exception as e:
except Exception:
print("[yellow]![/yellow] SQLite database out of sync, recreating from scratch")
# Ask for confirmation before dropping all tables
confirm = input(
Expand Down
4 changes: 2 additions & 2 deletions backend/pyspur/database.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os
from typing import Iterator
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session

from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker

# Get the database URL from the environment
POSTGRES_USER = os.getenv("POSTGRES_USER")
Expand Down
7 changes: 4 additions & 3 deletions backend/pyspur/models/management/alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# ruff: noqa: F401
from logging.config import fileConfig

from alembic import context
Expand All @@ -8,9 +9,9 @@
from pyspur.models.base_model import BaseModel
from pyspur.models.dataset_model import DatasetModel # type: ignore
from pyspur.models.dc_and_vi_model import (
DocumentCollectionModel,
VectorIndexModel,
) # type: ignore
DocumentCollectionModel, # type: ignore
VectorIndexModel, # type: ignore
)
from pyspur.models.eval_run_model import EvalRunModel # type: ignore
from pyspur.models.output_file_model import OutputFileModel # type: ignore
from pyspur.models.run_model import RunModel # type: ignore
Expand Down