Note: This is a fork of python-nocodb with extended functionality.
NocoDB is a great Airtable alternative. This client allows python developers to use NocoDB API in a simple way.
- 🚀 NocoDB Python Client
Since this is a fork with additional functionality, install directly from the GitHub repository:
pip install git+https://github.com/DeepCognition/python-nocodb.gitDevelopment Installation
git clone https://github.com/DeepCognition/python-nocodb.git
cd python-nocodb
pip install -e .Original Package
If you want the original package without the enhancements:
pip install nocodbfromnocodb.nocodbimportNocoDBProject, APIToken, JWTAuthTokenfromnocodb.filtersimportLikeFilter, EqFilter, Andfromnocodb.infra.requests_clientimportNocoDBRequestsClient# Usage with API Tokenclient=NocoDBRequestsClient(
# Your API Token retrieved from NocoDB confAPIToken("YOUR-API-TOKEN"),
# Your nocodb root path"http://localhost:8080"
)
# Usage with JWT Tokenclient=NocoDBRequestsClient(
# Your API Token retrieved from NocoDB confJWTAuthToken("your.jwt.token"),
# Your nocodb root path"http://localhost:8080"
)# Example with default databaseproject_body= {"title": "My new project"}
# Example with Postgresqlproject_body= {
"title": "MyProject",
"bases": [
{
"type": "pg",
"config": {
"client": "pg",
"connection": {
"host": "localhost",
"port": "5432",
"user": "postgres",
"password": "postgres",
"database": "postgres"
},
"searchPath": [
"public"
]
},
"inflection_column": "camelize",
"inflection_table": "camelize"
}
],
"external": True
}
project=client.project_create(body=project_body)# Be very carefull with org, project_name and table names# weird errors from nocodb can arrive if they are wrong# example: id is not defined...# probably they will fix that in a future release.project=NocoDBProject(
"noco", # org name. noco by default"myproject"# project name. Case sensitive!!
)table_name="tablename"# Retrieve a page of rows from a tabletable_rows=client.table_row_list(project, table_name)
# Retrieve the first 1000 rowstable_rows=client.table_row_list(project, table_name, params={'limit': 1000})
# Skip 100 rowstable_rows=client.table_row_list(project, table_name, params={'offset': 100})Pagination example
first_100_rows=client.table_row_list(project, table_name, params={'limit': 100})
next_100_rows=client.table_row_list(project, table_name, params={'limit': 100, 'offset': 100})
next_100_rows=client.table_row_list(project, table_name, params={'limit': 100, 'offset': 200})More row operations
# Filter the querytable_rows=client.table_row_list(project, table_name, LikeFilter("name", "%sam%"))
table_rows=client.table_row_list(project, table_name, And(LikeFilter("name", "%sam%"), EqFilter("age", 26)))
table_rows=client.table_row_list(project, table_name, filter_obj=EqFilter("Id", 100))
# Filter and count rowscount=client.table_count(project, table_name, filter_obj=EqFilter("Id", 100))
# Find one rowtable_row=client.table_find_one(project, table_name, filter_obj=EqFilter("Id", 100), params={"sort": "-created_at"})
# Retrieve a single rowrow_id=10row=client.table_row_detail(project, table_name, row_id)
# Create a new rowrow_info= {
"name": "my thoughts",
"content": "i'm going to buy samuel a beer 🍻 because I 💚 this module",
"mood": ":)"
}
client.table_row_create(project, table_name, row_info)
# Update a rowrow_id=2row_info= {
"content": "i'm going to buy samuel a new car 🚙 because I 💚 this module",
}
client.table_row_update(project, table_name, row_id, row_info)
# Bulk insert multiple rowsrows_to_insert= [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 28},
]
client.table_row_bulk_insert(project, table_name, rows_to_insert)
# Delete a row (only if you've already bought me a beer)client.table_row_delete(project, table_name, row_id)# List all tables in a projecttables=client.table_list(project)
# Read table metadatatable_id="table_id_from_table_list"table_metadata=client.table_read(table_id)
# Get detailed table infotable_info=client.table_info(table_id)
# Create a new tabletable_body= {
"table_name": "NewTableName",
"columns": [
{
"title": "Title",
"column_name": "title",
"dt": "varchar"
},
{
"title": "Description",
"column_name": "description",
"dt": "text"
}
]
}
client.table_create(project, table_body)
# Update a tabletable_update_body= {
"table_name": "UpdatedTableName"
}
client.table_update(table_id, table_update_body)
# Reorder a tableclient.table_reorder(table_id, order=2)
# Delete a tableclient.table_delete(table_id)# Create a new column in a tablecolumn_body= {
"title": "Rating",
"column_name": "rating",
"dt": "int"
}
client.table_column_create(table_id, column_body)
# Update a columncolumn_id="column_id_from_table_info"column_update_body= {
"title": "Score"
}
client.table_column_update(column_id, column_update_body)
# Set a column as primaryclient.table_column_set_primary(column_id)
# Delete a columnclient.table_column_delete(column_id)# Create a filter for a viewview_id="view_id_from_view_list"filter_body= {
"comparison_op": "eq",
"value": "Active",
"fk_column_id": column_id
}
client.view_filter_create(view_id, filter_body)# Get users for a project with paginationusers_page=client.project_users_list(
project, page=1, page_size=25, include_roles=True
)
# Get all users for a project (automatically handles pagination)all_users=client.project_users_list_all(
project, include_roles=True
)- EqFilter
- EqualFilter (Alias of EqFilter)
- NotEqualFilter
- GreaterThanFilter
- GreaterOrEqualFilter
- LessThanFilter
- LessOrEqualFilter
- LikeFilter
- Or
- Not
- And
fromnocodbimportfilters# Basic filters...nick_filter=filters.EqFilter("nickname", "elchicodepython")
country_filter=filters.EqFilter("country", "es")
girlfriend_code=filters.EqFilter("gfcode", "404")
current_mood_code=filters.EqFilter("moodcode", "418")
# Combining filters using logical filtersor_filter=filters.Or(nick_filter, country_filter)
and_filter=filters.And(girlfriend_code, current_mood_code)
# Negating filters with a Not filternot_me=filters.Not(filters.EqFilter("nickname", "elchicodepython"))
# You can also combine combinationsor_combined_filter=filters.Or(or_filter, and_filter)
and_combined_filter=filters.And(or_filter, and_filter)Nocodb is evolving and new operators are coming with each release.
Most of the basic operations are inside this package but you could need some new feature that could not be added yet. For those filters you can build your own.
Example for basic filters:
fromnocodb.filters.factoryimportbasic_filter_class_factoryBasicFilter=basic_filter_class_factory('=')
table_rows=client.table_row_list(project, table_name, BasicFilter('age', '16'))You can find the updated list of all the available nocodb operators here.
In some cases you might want to write your own filter string as described in the previous link. For that cases you can use the less-semmantic RawFilter.
fromnocodb.filters.raw_filterimportRawFiltertable_rows=client.table_row_list(project, table_name, RawFilter('(birthday,eq,exactDate,2023-06-01)'))In some cases we might want to have a file with some custom raw filters already defined by us.
We can easily create custom raw filter classes using raw_template_filter_class_factory.
fromnocodb.filters.factoryimportraw_template_filter_class_factoryBirthdayDateFilter=raw_template_filter_class_factory('(birthday,eq,exactDate,{})')
ExactDateEqFilter=raw_template_filter_class_factory('({},eq,exactDate,{})')
ExactDateOpFilter=raw_template_filter_class_factory('({},{op},exactDate,{})')
table_rows=client.table_row_list(project, table_name, BirthdayDateFilter('2023-06-01'))
table_rows=client.table_row_list(project, table_name, ExactDateEqFilter('column', '2023-06-01'))
table_rows=client.table_row_list(project, table_name, ExactDateOpFilter('column', '2023-06-01', op='eq'))Credits to @MitPitt for asking this feature.
I created this package to bootstrap some personal projects and I hope it will help other developers from the python community. It's not completed but it has what I needed: A full CRUD with some filters.
Feel free to add new capabilities by creating a new MR.
| Feature Category | Capabilities |
|---|---|
| 📝 Row Operations | Create, Read, Update, Delete, Bulk Insert |
| 📊 Table Management | Create, List, Read, Update, Delete, Reorder |
| 🔢 Column Management | Create, Update, Delete, Set Primary |
| 👥 User Management | List with pagination, List all users |
| 🔍 Filtering | Multiple filter types, Custom filters, Combined conditions |
| 🔎 Query Options | Sorting, Pagination, Field selection |
| 🚀 Efficient Bulk operations support | 🛠️ Complete Full CRUD functionality | 🔍 Flexible Advanced filtering |
| 🧩 Extensible Custom filter support | 👥 Collaborative User management | 📊 Powerful Table & column operations |
graph TD
A[Client Application] -->|uses| B(NocoDBClient)
B -->|implements| C[NocoDBRequestsClient]
C -->|uses| D[NocoDBAPI]
D -->|constructs| E[API URIs]
C -->|sends| F[HTTP Requests]
F -->|to| G[NocoDB Server]
- Samuel López Saura @elchicodepython
- Ilya Sapunov @davert0
- Delena Malan @delenamalan
- Jan Scheiper @jangxx
- Santosh Ray - VP of Technology @santoshray02 (DeepCognition)
- Added bulk insert functionality
- Refactored project identification to use project_id instead of project_name in API endpoints
- Implemented and fixed project users listing functionality
- Added user API endpoints
- Created view filter implementation
- Added table_info function to retrieve table metadata
- Fixed UnicodeDecodeError by specifying UTF-8 encoding when reading README.md
- Enhanced documentation for all features