tokenator 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tokenator/migrations.py +25 -27
- tokenator/schemas.py +7 -1
- tokenator/utils.py +39 -25
- {tokenator-0.1.0.dist-info → tokenator-0.1.2.dist-info}/METADATA +1 -1
- {tokenator-0.1.0.dist-info → tokenator-0.1.2.dist-info}/RECORD +7 -7
- {tokenator-0.1.0.dist-info → tokenator-0.1.2.dist-info}/LICENSE +0 -0
- {tokenator-0.1.0.dist-info → tokenator-0.1.2.dist-info}/WHEEL +0 -0
tokenator/migrations.py
CHANGED
@@ -1,40 +1,38 @@
|
|
1
1
|
"""Automatic database migrations manager."""
|
2
2
|
|
3
3
|
import os
|
4
|
+
import logging
|
4
5
|
from pathlib import Path
|
5
6
|
from alembic import command
|
6
7
|
from alembic.config import Config
|
7
8
|
from alembic.runtime.migration import MigrationContext
|
8
|
-
from alembic.script import ScriptDirectory
|
9
9
|
from sqlalchemy import create_engine
|
10
10
|
|
11
11
|
from .utils import get_default_db_path
|
12
12
|
|
13
|
-
|
14
|
-
"""Get Alembic config pointing to the package's migrations."""
|
15
|
-
package_dir = Path(__file__).parent
|
16
|
-
migrations_dir = package_dir / "migrations"
|
17
|
-
|
18
|
-
alembic_cfg = Config()
|
19
|
-
alembic_cfg.set_main_option("script_location", str(migrations_dir))
|
20
|
-
alembic_cfg.set_main_option("sqlalchemy.url", f"sqlite:///{get_default_db_path()}")
|
21
|
-
|
22
|
-
return alembic_cfg
|
13
|
+
logger = logging.getLogger(__name__)
|
23
14
|
|
24
15
|
def check_and_run_migrations():
|
25
|
-
"""Check
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
16
|
+
"""Check and run any pending database migrations."""
|
17
|
+
try:
|
18
|
+
db_path = get_default_db_path()
|
19
|
+
engine = create_engine(f"sqlite:///{db_path}")
|
20
|
+
|
21
|
+
# Create migrations table if it doesn't exist
|
22
|
+
with engine.connect() as conn:
|
23
|
+
context = MigrationContext.configure(conn)
|
24
|
+
current_rev = context.get_current_revision()
|
25
|
+
|
26
|
+
if current_rev is None:
|
27
|
+
# Run migrations
|
28
|
+
config = Config()
|
29
|
+
migrations_dir = os.path.join(os.path.dirname(__file__), "migrations")
|
30
|
+
config.set_main_option("script_location", migrations_dir)
|
31
|
+
config.set_main_option("sqlalchemy.url", f"sqlite:///{db_path}")
|
32
|
+
|
33
|
+
command.upgrade(config, "head")
|
34
|
+
logger.info("Database migrations completed successfully")
|
35
|
+
except Exception as e:
|
36
|
+
logger.error(f"Failed to run migrations: {e}")
|
37
|
+
# Don't raise the exception - allow the application to continue
|
38
|
+
# The user can manually initialize the DB later if needed
|
tokenator/schemas.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
import uuid
|
4
4
|
from datetime import datetime
|
5
|
+
import os
|
5
6
|
|
6
7
|
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Float, Index
|
7
8
|
from sqlalchemy.orm import sessionmaker, scoped_session, declarative_base
|
@@ -12,7 +13,12 @@ Base = declarative_base()
|
|
12
13
|
|
13
14
|
def get_engine(db_path: str = None):
|
14
15
|
"""Create SQLAlchemy engine with the given database path."""
|
15
|
-
|
16
|
+
if db_path is None:
|
17
|
+
try:
|
18
|
+
import google.colab # type: ignore
|
19
|
+
db_path = '/content/tokenator.db'
|
20
|
+
except ImportError:
|
21
|
+
db_path = get_default_db_path()
|
16
22
|
return create_engine(f"sqlite:///{db_path}", echo=False)
|
17
23
|
|
18
24
|
def get_session(db_path: str = None):
|
tokenator/utils.py
CHANGED
@@ -2,34 +2,48 @@
|
|
2
2
|
|
3
3
|
import os
|
4
4
|
import platform
|
5
|
+
import logging
|
5
6
|
from pathlib import Path
|
6
7
|
from typing import Optional
|
7
8
|
|
9
|
+
logger = logging.getLogger(__name__)
|
10
|
+
|
11
|
+
def is_colab() -> bool:
|
12
|
+
"""Check if running in Google Colab."""
|
13
|
+
try:
|
14
|
+
import google.colab # type: ignore
|
15
|
+
return True
|
16
|
+
except ImportError:
|
17
|
+
return False
|
18
|
+
|
8
19
|
def get_default_db_path() -> str:
|
9
|
-
"""Get the platform-specific default database path.
|
10
|
-
|
11
|
-
Returns:
|
12
|
-
str: Path to the SQLite database file
|
13
|
-
|
14
|
-
The path follows platform conventions:
|
15
|
-
- Linux/macOS: ~/.local/share/tokenator/usage.db (XDG spec)
|
16
|
-
- Windows: %LOCALAPPDATA%\\tokenator\\usage.db
|
17
|
-
- Others: ~/.tokenator/usage.db
|
18
|
-
"""
|
20
|
+
"""Get the platform-specific default database path."""
|
19
21
|
system = platform.system().lower()
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
23
|
+
try:
|
24
|
+
if is_colab():
|
25
|
+
# We're in Colab - use current directory
|
26
|
+
db_path = os.path.join(os.getcwd(), "tokenator_usage.db")
|
27
|
+
elif system == "linux" or system == "darwin":
|
28
|
+
# Follow XDG Base Directory Specification
|
29
|
+
xdg_data_home = os.environ.get("XDG_DATA_HOME", "")
|
30
|
+
if not xdg_data_home:
|
31
|
+
xdg_data_home = os.path.join(str(Path.home()), ".local", "share")
|
32
|
+
db_path = os.path.join(xdg_data_home, "tokenator", "usage.db")
|
33
|
+
elif system == "windows":
|
34
|
+
# Use %LOCALAPPDATA% on Windows
|
35
|
+
local_app_data = os.environ.get("LOCALAPPDATA", "")
|
36
|
+
if not local_app_data:
|
37
|
+
local_app_data = os.path.join(str(Path.home()), "AppData", "Local")
|
38
|
+
db_path = os.path.join(local_app_data, "tokenator", "usage.db")
|
39
|
+
else:
|
40
|
+
db_path = os.path.join(str(Path.home()), ".tokenator", "usage.db")
|
41
|
+
|
42
|
+
# Create directory if it doesn't exist
|
43
|
+
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
44
|
+
return db_path
|
45
|
+
except (OSError, IOError) as e:
|
46
|
+
# Fallback to current directory if we can't create the default path
|
47
|
+
fallback_path = os.path.join(os.getcwd(), "tokenator_usage.db")
|
48
|
+
logger.warning(f"Could not create default db path, falling back to {fallback_path}. Error: {e}")
|
49
|
+
return fallback_path
|
@@ -5,12 +5,12 @@ tokenator/client_openai.py,sha256=1xZuRA90kwlflTwEuFkXJHHN584XTeNh1CfEBMLELbQ,63
|
|
5
5
|
tokenator/create_migrations.py,sha256=C_3WqB0tOGKXOA4JmvWuLpcyGEysWyRSiSttxX-Kie4,606
|
6
6
|
tokenator/migrations/env.py,sha256=eFTw66gG464JV53740RKU32wqEL8uZFReS_INrvkFrU,1414
|
7
7
|
tokenator/migrations/script.py.mako,sha256=nJL-tbLQE0Qy4P9S4r4ntNAcikPtoFUlvXe6xvm9ot8,635
|
8
|
-
tokenator/migrations.py,sha256=
|
8
|
+
tokenator/migrations.py,sha256=RHm5XI5qh6W-Ib06vz4bXmE9XL211n1lZLzQNHPoSzg,1396
|
9
9
|
tokenator/models.py,sha256=EprE_MMJxDS-YXlcIQLZzfekH7xTYbeOC3bx3B2osVw,1171
|
10
|
-
tokenator/schemas.py,sha256=
|
10
|
+
tokenator/schemas.py,sha256=eVdBWi6_hTETnPw50glq0OvSh3PbP2pLl_aHdf3fi-M,2278
|
11
11
|
tokenator/usage.py,sha256=aHjGwzDzaiVznahNk5HqVyk3IxDo5FtFVfOUCeE7DZ4,7833
|
12
|
-
tokenator/utils.py,sha256=
|
13
|
-
tokenator-0.1.
|
14
|
-
tokenator-0.1.
|
15
|
-
tokenator-0.1.
|
16
|
-
tokenator-0.1.
|
12
|
+
tokenator/utils.py,sha256=UHV6tKLd6zoz7Fml1LokkbGmN1hvQMfXDY4Aulkhar8,1910
|
13
|
+
tokenator-0.1.2.dist-info/LICENSE,sha256=wdG-B6-ODk8RQ4jq5uXSn0w1UWTzCH_MMyvh7AwtGns,1074
|
14
|
+
tokenator-0.1.2.dist-info/METADATA,sha256=VnT8VlRydPmUPqNUesUjrhWWJT1PlliNriCRHAqrRtY,2444
|
15
|
+
tokenator-0.1.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
16
|
+
tokenator-0.1.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|