How to use baserow in Python shell? (no module named ‘baserow’)

Hello,

How can I use baserow from Python? I read the database plugin page which mentions importing:

from baserow.contrib.database.table.models import Table

But I get: no module named ‘baserow’

I found /baserow/venv in the docker image, but even after I activate the virtual environment I’m unable to import the baserow module.

I would like to access the Django model created in Baserow from an external Python script. Is it possible?

Hey @rtr ,

It depends where your code is when you write that import statement.

If your code is somewhere in an unrelated directory, then Python has no clue what baserow is, since baserow.contrib.database.table.model is just a path to a file assuming you are in the baserow project.

Hey @rtr,

if it’s ok for you to work in the backend container, what I usually do is give these commands inside the Baserow project folder:

$ docker compose exec backend bash
$ source ../venv/bin/activate
$ ./baserow shell_plus

In this way, you’ll also have all the Django models loaded.

Thank you. When I run ./baserow shell_plus I get this:

(venv) root@9a76e57d0608:/baserow/backend# ./baserow shell_plus
Traceback (most recent call last):
  File "./baserow", line 5, in <module>
    main()
  File "/baserow/backend/src/baserow/manage.py", line 26, in main
    if settings.DEBUG and os.environ.get("RUN_MAIN"):
  File "/baserow/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 82, in __getattr__
    self._setup(name)
  File "/baserow/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 67, in _setup
    % (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

So I run this:

(venv) root@9a76e57d0608:/baserow/backend# export DJANGO_SETTINGS_MODULE='baserow.config.settings.base'

But I still get errors:

(venv) root@9a76e57d0608:/baserow/backend# ./baserow shell_plus
WARNING: Baserow is configured to use a BASEROW_PUBLIC_URL of http://localhost. If you attempt to access Baserow on any other hostname requests to the backend will fail as they will be from an unknown host. Please set BASEROW_PUBLIC_URL if you will be accessing Baserow from any other URL then http://localhost.
Traceback (most recent call last):
  File "./baserow", line 5, in <module>
    main()
  File "/baserow/backend/src/baserow/manage.py", line 37, in main
    execute_from_command_line(sys.argv)
  File "/baserow/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/baserow/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
    django.setup()
  File "/baserow/venv/lib/python3.7/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/baserow/venv/lib/python3.7/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/baserow/backend/src/baserow/core/apps.py", line 57, in ready
    from .job_types import DuplicateApplicationJobType
  File "/baserow/backend/src/baserow/core/job_types.py", line 7, in <module>
    from baserow.api.applications.serializers import ApplicationSerializer
  File "/baserow/backend/src/baserow/api/applications/serializers.py", line 3, in <module>
    from drf_spectacular.openapi import OpenApiTypes
  File "/baserow/venv/lib/python3.7/site-packages/drf_spectacular/openapi.py", line 13, in <module>
    from rest_framework.generics import CreateAPIView, GenericAPIView, ListCreateAPIView
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/generics.py", line 9, in <module>
    from rest_framework import mixins, views
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/views.py", line 17, in <module>
    from rest_framework.schemas import DefaultSchema
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/schemas/__init__.py", line 33, in <module>
    authentication_classes=api_settings.DEFAULT_AUTHENTICATION_CLASSES,
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/settings.py", line 225, in __getattr__
    val = perform_import(val, attr)
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/settings.py", line 168, in perform_import
    return [import_from_string(item, setting_name) for item in val]
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/settings.py", line 168, in <listcomp>
    return [import_from_string(item, setting_name) for item in val]
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework/settings.py", line 177, in import_from_string
    return import_string(val)
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/baserow/backend/src/baserow/api/authentication.py", line 6, in <module>
    from rest_framework_jwt.authentication import (
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework_jwt/authentication.py", line 17, in <module>
    from rest_framework_jwt.blacklist.exceptions import (
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework_jwt/blacklist/exceptions.py", line 5, in <module>
    from rest_framework_jwt.compat import gettext_lazy as _
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework_jwt/compat.py", line 11, in <module>
    from .settings import api_settings
  File "/baserow/venv/lib/python3.7/site-packages/rest_framework_jwt/settings.py", line 14, in <module>
    'JWT_SECRET_KEY': settings.SECRET_KEY,
  File "/baserow/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 90, in __getattr__
    raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
(venv) root@9a76e57d0608:/baserow/backend#

Getting closer…

(venv) root@9a76e57d0608:/baserow/backend# export DJANGO_SETTINGS_MODULE='baserow.config.settings.dev'
(venv) root@9a76e57d0608:/baserow/backend/src# python -m pip install -r ../requirements/dev.txt
(venv) root@9a76e57d0608:/baserow/backend/src# baserow shell_plus
...
>>> from baserow.contrib.database.table.models import Table
>>>

Progress!

But then I get:

>>> Table.objects.get()
Traceback (most recent call last):
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 33, in inner
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 33, in inner
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/baserow/venv/lib/python3.7/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/query.py", line 431, in get
    num = len(clone)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/query.py", line 262, in __len__
    self._fetch_all()
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/query.py", line 1324, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/query.py", line 51, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1173, in execute_sql
    cursor = self.connection.cursor()
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 33, in inner
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    self.ensure_connection()
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 33, in inner
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/baserow/venv/lib/python3.7/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 33, in inner
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/baserow/venv/lib/python3.7/site-packages/django/utils/asyncio.py", line 33, in inner
    return func(*args, **kwargs)
  File "/baserow/venv/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/baserow/venv/lib/python3.7/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known

>>>

Ok, got it, I think :crossed_fingers:

>>> pw = open('/baserow/data/.pgpass').read().split('=')[1].strip()
>>> settings.DATABASES['default']['HOST'] = 'localhost'
>>> settings.DATABASES['default']['PASSWORD'] = pw
>>> model = Table.objects.get(pk=313).get_model(attribute_names=True)
>>> model.objects.all()
<TableModelQuerySet [<Table313Model: Yellow>, <Table313Model: Brown>]>
>>> model.objects.first().name
'Yellow'
2 Likes

I also had similar issue and thought about building a Baserow wrapper that could look like this.

from baserow import Baserow

bsr = Baserow(url='https://your.baserowinstance.com', token='SECRET_TOKEN')

# bsr is built by gathering all possible databases and tables that
# can be accessible with the token specified

# As instance, let's say token gives access to a single database 'customers' with a table 'general'

customers = bsr.get_database(name = 'customers')
# or
customers = bsr.get_database(id = 2345)

# access data
first_customer = customers.get(name='John doe')  

# its return a django-like object on which you can get the columns you want
first_customer.id
first_customer.email

We could create the dedicated repository somewhere and advertize it to the community, since I personnaly do not have time currently to work on it.