diff --git a/README.md b/README.md index 51cdd7f..51e2987 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ NocoDB is a great Airtable alternative. This client allows python developers to use NocoDB API in a simple way. +- [Contributors guidelines](contributors.md) + ## Installation ```bash @@ -14,7 +16,7 @@ pip install nocodb ### Client configuration ```python from nocodb.nocodb import NocoDBProject, APIToken, JWTAuthToken -from nocodb.filters import LikeFilter, EqFilter +from nocodb.filters import LikeFilter, EqFilter, And from nocodb.infra.requests_client import NocoDBRequestsClient @@ -89,16 +91,31 @@ table_name = "tablename" # Retrieve a page of rows from a table table_rows = client.table_row_list(project, table_name) -# Retrieve the first 10000 rows -table_rows = client.table_row_list(project, table_name, params={'limit': 10000}) +# Retrieve the first 1000 rows +table_rows = client.table_row_list(project, table_name, params={'limit': 1000}) # Skip 100 rows table_rows = client.table_row_list(project, table_name, params={'offset': 100}) +``` + +⚠️ Seems that we can't retrieve more than 1000 rows at the same time but we can paginate + to retrieve all the rows from a table + +Pagination example + +```python + +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 +```python # Filter the query -# Currently only one filter at a time is allowed. I don't know how to join -# multiple conditions in nocodb dsl. If you know how please let me know :). table_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 rows @@ -140,6 +157,33 @@ client.table_row_delete(project, table_name, row_id) - LessThanFilter - LessOrEqualFilter - LikeFilter +- Or +- Not +- And + +#### Combining filters using Logical operations + +```python +from nocodb import filters + +# 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 filters +or_filter = filters.Or(nick_filter, country_filter) +and_filter = filters.And(girlfriend_code, current_mood_code) + +# Negating filters with a Not filter +not_me = filters.Not(filters.EqFilter("nickname", "elchicodepython")) + +# You can also combine combinations +or_combined_filter = filters.Or(or_filter, and_filter) +and_combined_filter = filters.And(or_filter, and_filter) + +``` ### Using custom filters @@ -185,27 +229,6 @@ table_rows = client.table_row_list(project, table_name, ExactDateEqFilter('colum table_rows = client.table_row_list(project, table_name, ExactDateOpFilter('column', '2023-06-01', op='eq')) ``` -```python -from nocodb import filters - -# 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 filters -or_filter = filters.Or(nick_filter, country_filter) -and_filter = filters.And(girlfriend_code, current_mood_code) - -# Negating filters with a Not filter -not_me = filters.Not(filters.EqFilter("nickname", "elchicodepython")) - -# You can also combine combinations -or_combined_filter = filters.Or(or_filter, and_filter) -and_combined_filter = filters.And(or_filter, and_filter) - -``` Credits to @MitPitt for asking this feature. diff --git a/contributors.md b/contributors.md new file mode 100644 index 0000000..514fa6b --- /dev/null +++ b/contributors.md @@ -0,0 +1,81 @@ +# Contributor Guidelines for python-nocodb + +Welcome to python-nocodb! We're excited that you want to contribute to our open-source project. Please take a moment to read and follow these guidelines to ensure a smooth and collaborative development process. + +## Table of Contents + +- [Contribution Process](#contribution-process) + - [1. Fork the Repository](#1-fork-the-repository) + - [2. Create a Branch](#2-create-a-branch) + - [3. Work on Your Contribution](#3-work-on-your-contribution) + - [4. Test Your Code](#4-test-your-code) + - [5. Commit Your Changes](#5-commit-your-changes) + - [6. Create a Pull Request](#6-create-a-pull-request) +- [Coding Guidelines](#coding-guidelines) +- [Documentation](#documentation) +- [Authors](#authors) + +## Contribution Process + +To contribute to this project, follow these steps: + +### 1. Fork the Repository + +Click the "Fork" button on the top right corner of the repository's page on GitHub. This will create a copy of the repository in your GitHub account. + +### 2. Create a Branch + +Clone your forked repository to your local machine, then create a new branch for your contribution. Name your branch in a descriptive manner that reflects the purpose of your contribution. + +```bash +git clone https://github.com/your-username/python-nocodb.git +cd python-nocodb +git checkout -b feature/your-feature +``` + +### 3. Work on Your Contribution + +Now you can start working on your contribution. Be sure to follow the coding guidelines (mentioned below) and implement your changes or new features. + +### 4. Test Your Code + +Thoroughly test your code to ensure it works as expected. Make sure to write unit tests, if applicable. Your contribution should not introduce new bugs or regressions. + +### 5. Commit Your Changes + +Once you are satisfied with your work, commit your changes. Be sure to write clear and descriptive commit messages. + +```bash +git add . +git commit -m "Add a clear and concise commit message" +``` + +### 6. Create a Pull Request + +When your code is ready for review, push your changes to your forked repository, and then open a Pull Request (PR) to the main repository's `main` branch. In your PR description, provide a clear and detailed explanation of your contribution, including what the change does and why it is needed. + +Our team will review your PR, provide feedback, and merge it when it meets our quality and functionality standards. + +## Coding Guidelines + +Please adhere to the following coding guidelines: + +- Follow the style and conventions used in the existing codebase. +- Write clean, readable, and well-documented code. +- Keep code modular and DRY (Don't Repeat Yourself). +- Ensure your code is consistent with the project's coding standards. +- Include unit tests when adding new functionality. + +## Documentation + +Documentation is crucial for maintaining and improving our project. When you make a contribution, you should: + +- Update or add documentation to explain the new capabilities or changes you've made. +- Include comments within your code to explain complex logic or important decisions. +- If you add or change a feature, update the project's README to reflect these changes. + +## Authors + +We appreciate all contributors to our project. To give credit where it's due, please add your name and GitHub username to the "Authors" section of the README if it's not already there. + +Thank you for your interest in contributing to python-nocodb. We look forward to your contributions and collaborations. Happy coding! diff --git a/nocodb/__init__.py b/nocodb/__init__.py index 8c0d5d5..159d48b 100644 --- a/nocodb/__init__.py +++ b/nocodb/__init__.py @@ -1 +1 @@ -__version__ = "2.0.0" +__version__ = "2.0.1" diff --git a/nocodb/filters/logical.py b/nocodb/filters/logical.py index f3fbc8e..94379a2 100644 --- a/nocodb/filters/logical.py +++ b/nocodb/filters/logical.py @@ -7,11 +7,7 @@ def __init__(self, *filters: List[WhereFilter]): self.__filters = filters def get_where(self) -> str: - return ( - "(" - + "~or".join([filter.get_where() for filter in self.__filters]) - + ")" - ) + return f"({'~or'.join([filter.get_where() for filter in self.__filters])})" class And(WhereFilter): @@ -19,11 +15,7 @@ def __init__(self, *filters: List[WhereFilter]): self.__filters = filters def get_where(self) -> str: - return ( - "(" - + "~and".join([filter.get_where() for filter in self.__filters]) - + ")" - ) + return f"({'~and'.join([filter.get_where() for filter in self.__filters])})" class Not(WhereFilter): @@ -31,4 +23,4 @@ def __init__(self, filter: WhereFilter): self.__filter = filter def get_where(self) -> str: - return "~not" + self.__filter.get_where() + return f"~not{self.__filter.get_where()}" diff --git a/nocodb/filters/logical_test.py b/nocodb/filters/logical_test.py new file mode 100644 index 0000000..d6865b6 --- /dev/null +++ b/nocodb/filters/logical_test.py @@ -0,0 +1,21 @@ +from nocodb import filters + + +def test_or_with_two_filters(): + filter1 = filters.EqFilter("column1", "value1") + filter2 = filters.EqFilter("column2", "value2") + or_filter = filters.Or(filter1, filter2) + assert or_filter.get_where() == "((column1,eq,value1)~or(column2,eq,value2))" + + +def test_and_with_two_filters(): + filter1 = filters.And(filters.EqFilter("column1", "value1")) + filter2 = filters.And(filters.EqFilter("column2", "value2")) + and_filter = filters.And(filter1, filter2) + assert and_filter.get_where() == "(((column1,eq,value1))~and((column2,eq,value2)))" + + +def test_not_filter(): + filter = filters.EqFilter("column", "value") + not_filter = filters.Not(filter) + assert not_filter.get_where() == "~not(column,eq,value)" diff --git a/nocodb/nocodb.py b/nocodb/nocodb.py index 3d7eb07..1fe801e 100644 --- a/nocodb/nocodb.py +++ b/nocodb/nocodb.py @@ -32,7 +32,7 @@ def get_header(self) -> dict: pass -class APIToken: +class APIToken(AuthToken): def __init__(self, token: str): self.__token = token @@ -40,7 +40,7 @@ def get_header(self) -> dict: return {"xc-token": self.__token} -class JWTAuthToken: +class JWTAuthToken(AuthToken): def __init__(self, token: str): self.__token = token diff --git a/setup.py b/setup.py index 7b52b3e..fd1d200 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='nocodb', - version='2.0.0', + version='2.0.1', author='Samuel López Saura', author_email='samuellopezsaura@gmail.com', packages=find_packages(),