[X] I have checked that this issue has not already been reported.
[X] I have confirmed this bug exists on the latest version of actualpy.
Reproducible example
test_actual.py
@pytest.fixture
def actual():
with Actual(base_url="http://localhost:6669", password="test", bootstrap=True) as actual:
actual.create_budget("TestBudget")
actual.upload_budget()
# This yield is my idea to setup pytest with actualpy, but I actually not sure if it will work
yield actual
actual.delete_budget()
def test_actual_connector(actual):
pass
but would probably reproduce on my env by just:
with Actual(base_url="http://localhost:6669", password="test", bootstrap=True) as actual:
actual.create_budget("TestBudget")
@pytest.fixture
def actual():
with Actual(base_url="http://localhost:6669", password="test", bootstrap=True) as actual:
> actual.create_budget("Test Budget")
tests/conftest.py:15:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.12/site-packages/actual/__init__.py:192: in create_budget
self.run_migrations(migration_files[1:])
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <actual.Actual object at 0x7f90648404d0>
migration_files = ['migrations/1548957970627_remove-db-version.sql', 'migrations/1550601598648_payees.sql', 'migrations/1555786194328_re...rations/1561751833510_indexes.sql', 'migrations/1567699552727_budget.sql', 'migrations/1582384163573_cleared.sql', ...]
def run_migrations(self, migration_files: list[str]):
"""Runs the migration files, skipping the ones that have already been run. The files can be retrieved from
.data_file_index() method. This first file is the base database, and the following files are migrations.
Migrations can also be .js files. In this case, we have to extract and execute queries from the standard JS."""
conn = sqlite3.connect(self._data_dir / "db.sqlite")
for file in migration_files:
if not file.startswith("migrations"):
continue # in case db.sqlite file gets passed as one of the migrations files
file_id = file.split("_")[0].split("/")[1]
if conn.execute(f"SELECT id FROM __migrations__ WHERE id = '{file_id}';").fetchall():
continue # skip migration as it was already ran
migration = self.data_file(file) # retrieves file from actual server
sql_statements = migration.decode()
if file.endswith(".js"):
# there is one migration which is Javascript. All entries inside db.execQuery(`...`) must be executed
exec_entries = js_migration_statements(sql_statements)
sql_statements = "\n".join(exec_entries)
> conn.executescript(sql_statements)
E sqlite3.OperationalError: near "DROP": syntax error
venv/lib/python3.12/site-packages/actual/__init__.py:156: OperationalError
============================================================== warnings summary
tests/test_actual_connector.py::test_actual_connector
/home/mbielecki/personal_projects/actual-discord-bot/venv/lib/python3.12/site-packages/actual/__init__.py:168: UserWarning: Creating budgets via actualpy is not recommended due to custom code migrations.
warnings.warn("Creating budgets via actualpy is not recommended due to custom code migrations.")
tests/test_actual_connector.py::test_actual_connector
/home/mbielecki/personal_projects/actual-discord-bot/venv/lib/python3.12/site-packages/actual/migrations.py:39: UserWarning: Migration query from migrations cannot be executed due to custom code, it will be skipped. Query:
INSERT INTO ${table} (id, month, category, amount, carryover) VALUES (?, ?, ?, ?, ?)
warnings.warn(
tests/test_actual_connector.py::test_actual_connector
/home/mbielecki/personal_projects/actual-discord-bot/venv/lib/python3.12/site-packages/actual/migrations.py:39: UserWarning: Migration query from migrations cannot be executed due to custom code, it will be skipped. Query:
INSERT INTO zero_budget_months (id, buffered) VALUES (?, ?)
warnings.warn(
tests/test_actual_connector.py::test_actual_connector
/home/mbielecki/personal_projects/actual-discord-bot/venv/lib/python3.12/site-packages/actual/migrations.py:39: UserWarning: Migration query from migrations cannot be executed due to custom code, it will be skipped. Query:
INSERT INTO notes (id, note) VALUES (?, ?)
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
Issue description
Hello,
I'm trying to use pytest to automatically test my code that is using actual.py.
I thought about having Actual server bootstrapped as part of test setup. However I'm encountering an error in create_budget() function.
Using pytest . --showlocals prints some more useful information, includiing rendered SQL query. (that does not actually look wrong to me)
aiohappyeyeballs 2.4.2 Happy Eyeballs for asyncio
aiohttp 3.10.8 Async http client/server framework (asyncio)
aiosignal 1.3.1 aiosignal: a list of registered asynchronous callbacks
annotated-types 0.7.0 Reusable constraint types to use with typing.Annotated
anyio 3.7.1 High level compatibility layer for multiple asynchronous event loop implementations
attrs 24.2.0 Classes Without Boilerplate
babel 2.16.0 Internationalization utilities
certifi 2024.8.30 Python package for providing Mozilla's CA Bundle.
cffi 1.17.1 Foreign Function Interface for Python calling C code.
charset-normalizer 3.3.2 The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
cogwatch 3.3.1 Automatic hot-reloading for your discord.py (or other supported libaries) command files.
cryptography 43.0.1 cryptography is a package which provides cryptographic recipes and primitives to Python developers.
discord 2.3.2 A mirror package for discord.py. Please install that instead.
discord-py 2.4.0 A Python wrapper for the Discord API
environ-config 24.1.0 Boilerplate-free configuration with env variables.
frozenlist 1.4.1 A list-like structure which implements collections.abc.MutableSequence
greenlet 3.1.1 Lightweight in-process concurrent programming
idna 3.10 Internationalized Domain Names in Applications (IDNA)
multidict 6.1.0 multidict implementation
mypy 1.11.2 Optional static typing for Python
mypy-extensions 1.0.0 Type system extensions for programs checked with the mypy type checker.
proto-plus 1.24.0 Beautiful, Pythonic protocol buffers.
protobuf 5.28.2
pycparser 2.22 C parser in Python
pydantic 2.9.2 Data validation using Python type hints
pydantic-core 2.23.4 Core functionality for Pydantic validation and serialization
python-dateutil 2.9.0.post0 Extensions to the standard Python datetime module
requests 2.32.3 Python HTTP for Humans.
six 1.16.0 Python 2 and 3 compatibility utilities
sniffio 1.3.1 Sniff out which async library your code is running under
sqlalchemy 2.0.35 Database Abstraction Library
sqlmodel 0.0.22 SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.
typing-extensions 4.12.2 Backported and Experimental Type Hints for Python 3.8+
urllib3 2.2.3 HTTP library with thread-safe connection pooling, file post, and more.
watchfiles 0.15.0 Simple, modern and high performance file watching and code reload in python.
yarl 1.13.1 Yet another URL library
Checks
Reproducible example
test_actual.py
but would probably reproduce on my env by just:
docker-compose.yml
Log output
Issue description
Hello,
I'm trying to use pytest to automatically test my code that is using actual.py. I thought about having Actual server bootstrapped as part of test setup. However I'm encountering an error in create_budget() function.
Using
pytest . --showlocals
prints some more useful information, includiing rendered SQL query. (that does not actually look wrong to me)Expected behavior
There is no error during
create_budget
functionInstalled versions
Python 3.12.6 actualpy 0.5.1 Actual server -
latest
docker tag - https://hub.docker.com/layers/actualbudget/actual-server/latest/images/sha256-4a0c0b71d3eb6c9b68c6922c97af4e5dd258c5a433fed30ef147cba8511a4914?context=exploreother packages in my environment: