teable-client 1.0.0__tar.gz
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.
- teable_client-1.0.0/LICENSE +21 -0
- teable_client-1.0.0/PKG-INFO +245 -0
- teable_client-1.0.0/README.md +205 -0
- teable_client-1.0.0/setup.cfg +4 -0
- teable_client-1.0.0/setup.py +43 -0
- teable_client-1.0.0/teable/__init__.py +66 -0
- teable_client-1.0.0/teable/exceptions/__init__.py +146 -0
- teable_client-1.0.0/teable_client.egg-info/PKG-INFO +245 -0
- teable_client-1.0.0/teable_client.egg-info/SOURCES.txt +10 -0
- teable_client-1.0.0/teable_client.egg-info/dependency_links.txt +1 -0
- teable_client-1.0.0/teable_client.egg-info/requires.txt +10 -0
- teable_client-1.0.0/teable_client.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Volkan Tasci
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: teable-client
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A professional Python client library for the Teable API
|
|
5
|
+
Home-page: https://github.com/volkantasci/teable-client
|
|
6
|
+
Author: Volkan Tasci
|
|
7
|
+
Author-email: volkantasci@gmail.com
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.7
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: requests>=2.25.0
|
|
22
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
23
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=6.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: black>=21.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: isort>=5.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: mypy>=0.900; extra == "dev"
|
|
30
|
+
Dynamic: author
|
|
31
|
+
Dynamic: author-email
|
|
32
|
+
Dynamic: classifier
|
|
33
|
+
Dynamic: description
|
|
34
|
+
Dynamic: description-content-type
|
|
35
|
+
Dynamic: home-page
|
|
36
|
+
Dynamic: provides-extra
|
|
37
|
+
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
40
|
+
|
|
41
|
+
# Teable Client Library
|
|
42
|
+
|
|
43
|
+
A professional Python client library for interacting with the Teable API. This library provides an object-oriented interface for managing tables, records, fields, and views in Teable.
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- Full Teable API coverage with an intuitive object-oriented interface
|
|
48
|
+
- Comprehensive field type support with validation
|
|
49
|
+
- Efficient batch operations for creating, updating, and deleting records
|
|
50
|
+
- Advanced querying capabilities with a fluent query builder
|
|
51
|
+
- Automatic rate limiting and retry handling
|
|
52
|
+
- Resource caching for improved performance
|
|
53
|
+
- Type hints for better IDE support
|
|
54
|
+
- Detailed documentation and examples
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
You can install the package using pip:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install teable-client
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from teable import TeableClient, TeableConfig
|
|
68
|
+
|
|
69
|
+
# Initialize the client
|
|
70
|
+
config = TeableConfig(
|
|
71
|
+
api_url="https://your-teable-instance.com/api",
|
|
72
|
+
api_key="your-api-key"
|
|
73
|
+
)
|
|
74
|
+
client = TeableClient(config)
|
|
75
|
+
|
|
76
|
+
# Get a table
|
|
77
|
+
table = client.get_table("table_id")
|
|
78
|
+
|
|
79
|
+
# Create a record
|
|
80
|
+
record = table.create_record({
|
|
81
|
+
"name": "John Doe",
|
|
82
|
+
"email": "john@example.com",
|
|
83
|
+
"age": 30
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
# Query records
|
|
87
|
+
query = table.query()\
|
|
88
|
+
.filter("age", ">", 25)\
|
|
89
|
+
.sort("name")\
|
|
90
|
+
.paginate(take=10)
|
|
91
|
+
|
|
92
|
+
records = table.get_records(query)
|
|
93
|
+
|
|
94
|
+
# Batch create records
|
|
95
|
+
records_data = [
|
|
96
|
+
{"name": "Alice", "age": 28},
|
|
97
|
+
{"name": "Bob", "age": 32}
|
|
98
|
+
]
|
|
99
|
+
batch_result = table.batch_create_records(records_data)
|
|
100
|
+
print(f"Created {batch_result.success_count} records")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Advanced Usage
|
|
104
|
+
|
|
105
|
+
### Working with Fields
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from teable import FieldType, Field
|
|
109
|
+
|
|
110
|
+
# Get table fields
|
|
111
|
+
fields = table.fields
|
|
112
|
+
|
|
113
|
+
# Access field properties
|
|
114
|
+
for field in fields:
|
|
115
|
+
print(f"{field.name} ({field.field_type})")
|
|
116
|
+
if field.is_required:
|
|
117
|
+
print(" Required field")
|
|
118
|
+
if field.is_primary:
|
|
119
|
+
print(" Primary field")
|
|
120
|
+
|
|
121
|
+
# Validate field values
|
|
122
|
+
field = table.get_field("field_id")
|
|
123
|
+
try:
|
|
124
|
+
field.validate_value(some_value)
|
|
125
|
+
except ValidationError as e:
|
|
126
|
+
print(f"Invalid value: {e}")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Using Views
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
# Get table views
|
|
133
|
+
views = table.views
|
|
134
|
+
|
|
135
|
+
# Get records from a specific view
|
|
136
|
+
view = table.get_view("view_id")
|
|
137
|
+
query = view.create_query().paginate(take=20)
|
|
138
|
+
records = table.get_records(query)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Advanced Querying
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from teable import FilterOperator, SortDirection
|
|
145
|
+
|
|
146
|
+
# Complex query with multiple conditions
|
|
147
|
+
query = table.query()\
|
|
148
|
+
.filter("status", FilterOperator.EQUALS, "active")\
|
|
149
|
+
.filter("age", FilterOperator.GREATER_THAN, 25)\
|
|
150
|
+
.filter("tags", FilterOperator.CONTAINS, "important")\
|
|
151
|
+
.sort("created_time", SortDirection.DESCENDING)\
|
|
152
|
+
.sort("priority")\
|
|
153
|
+
.search("urgent", field="title")\
|
|
154
|
+
.paginate(take=50, skip=100)
|
|
155
|
+
|
|
156
|
+
records = table.get_records(query)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Batch Operations
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
# Batch create
|
|
163
|
+
records_data = [
|
|
164
|
+
{"name": "Alice", "department": "Engineering"},
|
|
165
|
+
{"name": "Bob", "department": "Marketing"}
|
|
166
|
+
]
|
|
167
|
+
batch_result = table.batch_create_records(records_data)
|
|
168
|
+
|
|
169
|
+
print(f"Successfully created: {batch_result.success_count}")
|
|
170
|
+
if batch_result.failed:
|
|
171
|
+
print("Failed operations:")
|
|
172
|
+
for failure in batch_result.failed:
|
|
173
|
+
print(f" {failure}")
|
|
174
|
+
|
|
175
|
+
# Batch update
|
|
176
|
+
updates = [
|
|
177
|
+
{"id": "rec1", "fields": {"status": "completed"}},
|
|
178
|
+
{"id": "rec2", "fields": {"status": "completed"}}
|
|
179
|
+
]
|
|
180
|
+
table.batch_update_records(updates)
|
|
181
|
+
|
|
182
|
+
# Batch delete
|
|
183
|
+
record_ids = ["rec1", "rec2", "rec3"]
|
|
184
|
+
table.batch_delete_records(record_ids)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Error Handling
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from teable import (
|
|
191
|
+
TeableError,
|
|
192
|
+
APIError,
|
|
193
|
+
ValidationError,
|
|
194
|
+
ResourceNotFoundError
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
try:
|
|
198
|
+
record = table.get_record("invalid_id")
|
|
199
|
+
except ResourceNotFoundError as e:
|
|
200
|
+
print(f"Record not found: {e}")
|
|
201
|
+
except ValidationError as e:
|
|
202
|
+
print(f"Validation error: {e}")
|
|
203
|
+
except APIError as e:
|
|
204
|
+
print(f"API error {e.status_code}: {e}")
|
|
205
|
+
except TeableError as e:
|
|
206
|
+
print(f"Other error: {e}")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Configuration Options
|
|
210
|
+
|
|
211
|
+
The `TeableConfig` class supports various options to customize the client behavior:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
config = TeableConfig(
|
|
215
|
+
api_url="https://your-teable-instance.com/api",
|
|
216
|
+
api_key="your-api-key",
|
|
217
|
+
timeout=30.0, # Request timeout in seconds
|
|
218
|
+
max_retries=3, # Maximum number of retry attempts
|
|
219
|
+
retry_delay=1.0, # Delay between retries in seconds
|
|
220
|
+
default_table_id=None, # Default table ID for operations
|
|
221
|
+
default_view_id=None # Default view ID for operations
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
To set up the development environment:
|
|
228
|
+
|
|
229
|
+
1. Clone the repository
|
|
230
|
+
2. Install development dependencies:
|
|
231
|
+
```bash
|
|
232
|
+
pip install -e ".[dev]"
|
|
233
|
+
```
|
|
234
|
+
3. Run tests:
|
|
235
|
+
```bash
|
|
236
|
+
pytest
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Contributing
|
|
240
|
+
|
|
241
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
242
|
+
|
|
243
|
+
## License
|
|
244
|
+
|
|
245
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Teable Client Library
|
|
2
|
+
|
|
3
|
+
A professional Python client library for interacting with the Teable API. This library provides an object-oriented interface for managing tables, records, fields, and views in Teable.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Full Teable API coverage with an intuitive object-oriented interface
|
|
8
|
+
- Comprehensive field type support with validation
|
|
9
|
+
- Efficient batch operations for creating, updating, and deleting records
|
|
10
|
+
- Advanced querying capabilities with a fluent query builder
|
|
11
|
+
- Automatic rate limiting and retry handling
|
|
12
|
+
- Resource caching for improved performance
|
|
13
|
+
- Type hints for better IDE support
|
|
14
|
+
- Detailed documentation and examples
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
You can install the package using pip:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install teable-client
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from teable import TeableClient, TeableConfig
|
|
28
|
+
|
|
29
|
+
# Initialize the client
|
|
30
|
+
config = TeableConfig(
|
|
31
|
+
api_url="https://your-teable-instance.com/api",
|
|
32
|
+
api_key="your-api-key"
|
|
33
|
+
)
|
|
34
|
+
client = TeableClient(config)
|
|
35
|
+
|
|
36
|
+
# Get a table
|
|
37
|
+
table = client.get_table("table_id")
|
|
38
|
+
|
|
39
|
+
# Create a record
|
|
40
|
+
record = table.create_record({
|
|
41
|
+
"name": "John Doe",
|
|
42
|
+
"email": "john@example.com",
|
|
43
|
+
"age": 30
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
# Query records
|
|
47
|
+
query = table.query()\
|
|
48
|
+
.filter("age", ">", 25)\
|
|
49
|
+
.sort("name")\
|
|
50
|
+
.paginate(take=10)
|
|
51
|
+
|
|
52
|
+
records = table.get_records(query)
|
|
53
|
+
|
|
54
|
+
# Batch create records
|
|
55
|
+
records_data = [
|
|
56
|
+
{"name": "Alice", "age": 28},
|
|
57
|
+
{"name": "Bob", "age": 32}
|
|
58
|
+
]
|
|
59
|
+
batch_result = table.batch_create_records(records_data)
|
|
60
|
+
print(f"Created {batch_result.success_count} records")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Advanced Usage
|
|
64
|
+
|
|
65
|
+
### Working with Fields
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from teable import FieldType, Field
|
|
69
|
+
|
|
70
|
+
# Get table fields
|
|
71
|
+
fields = table.fields
|
|
72
|
+
|
|
73
|
+
# Access field properties
|
|
74
|
+
for field in fields:
|
|
75
|
+
print(f"{field.name} ({field.field_type})")
|
|
76
|
+
if field.is_required:
|
|
77
|
+
print(" Required field")
|
|
78
|
+
if field.is_primary:
|
|
79
|
+
print(" Primary field")
|
|
80
|
+
|
|
81
|
+
# Validate field values
|
|
82
|
+
field = table.get_field("field_id")
|
|
83
|
+
try:
|
|
84
|
+
field.validate_value(some_value)
|
|
85
|
+
except ValidationError as e:
|
|
86
|
+
print(f"Invalid value: {e}")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Using Views
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# Get table views
|
|
93
|
+
views = table.views
|
|
94
|
+
|
|
95
|
+
# Get records from a specific view
|
|
96
|
+
view = table.get_view("view_id")
|
|
97
|
+
query = view.create_query().paginate(take=20)
|
|
98
|
+
records = table.get_records(query)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Advanced Querying
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from teable import FilterOperator, SortDirection
|
|
105
|
+
|
|
106
|
+
# Complex query with multiple conditions
|
|
107
|
+
query = table.query()\
|
|
108
|
+
.filter("status", FilterOperator.EQUALS, "active")\
|
|
109
|
+
.filter("age", FilterOperator.GREATER_THAN, 25)\
|
|
110
|
+
.filter("tags", FilterOperator.CONTAINS, "important")\
|
|
111
|
+
.sort("created_time", SortDirection.DESCENDING)\
|
|
112
|
+
.sort("priority")\
|
|
113
|
+
.search("urgent", field="title")\
|
|
114
|
+
.paginate(take=50, skip=100)
|
|
115
|
+
|
|
116
|
+
records = table.get_records(query)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Batch Operations
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
# Batch create
|
|
123
|
+
records_data = [
|
|
124
|
+
{"name": "Alice", "department": "Engineering"},
|
|
125
|
+
{"name": "Bob", "department": "Marketing"}
|
|
126
|
+
]
|
|
127
|
+
batch_result = table.batch_create_records(records_data)
|
|
128
|
+
|
|
129
|
+
print(f"Successfully created: {batch_result.success_count}")
|
|
130
|
+
if batch_result.failed:
|
|
131
|
+
print("Failed operations:")
|
|
132
|
+
for failure in batch_result.failed:
|
|
133
|
+
print(f" {failure}")
|
|
134
|
+
|
|
135
|
+
# Batch update
|
|
136
|
+
updates = [
|
|
137
|
+
{"id": "rec1", "fields": {"status": "completed"}},
|
|
138
|
+
{"id": "rec2", "fields": {"status": "completed"}}
|
|
139
|
+
]
|
|
140
|
+
table.batch_update_records(updates)
|
|
141
|
+
|
|
142
|
+
# Batch delete
|
|
143
|
+
record_ids = ["rec1", "rec2", "rec3"]
|
|
144
|
+
table.batch_delete_records(record_ids)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Error Handling
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from teable import (
|
|
151
|
+
TeableError,
|
|
152
|
+
APIError,
|
|
153
|
+
ValidationError,
|
|
154
|
+
ResourceNotFoundError
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
record = table.get_record("invalid_id")
|
|
159
|
+
except ResourceNotFoundError as e:
|
|
160
|
+
print(f"Record not found: {e}")
|
|
161
|
+
except ValidationError as e:
|
|
162
|
+
print(f"Validation error: {e}")
|
|
163
|
+
except APIError as e:
|
|
164
|
+
print(f"API error {e.status_code}: {e}")
|
|
165
|
+
except TeableError as e:
|
|
166
|
+
print(f"Other error: {e}")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Configuration Options
|
|
170
|
+
|
|
171
|
+
The `TeableConfig` class supports various options to customize the client behavior:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
config = TeableConfig(
|
|
175
|
+
api_url="https://your-teable-instance.com/api",
|
|
176
|
+
api_key="your-api-key",
|
|
177
|
+
timeout=30.0, # Request timeout in seconds
|
|
178
|
+
max_retries=3, # Maximum number of retry attempts
|
|
179
|
+
retry_delay=1.0, # Delay between retries in seconds
|
|
180
|
+
default_table_id=None, # Default table ID for operations
|
|
181
|
+
default_view_id=None # Default view ID for operations
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Development
|
|
186
|
+
|
|
187
|
+
To set up the development environment:
|
|
188
|
+
|
|
189
|
+
1. Clone the repository
|
|
190
|
+
2. Install development dependencies:
|
|
191
|
+
```bash
|
|
192
|
+
pip install -e ".[dev]"
|
|
193
|
+
```
|
|
194
|
+
3. Run tests:
|
|
195
|
+
```bash
|
|
196
|
+
pytest
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Contributing
|
|
200
|
+
|
|
201
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="teable-client",
|
|
8
|
+
version="1.0.0",
|
|
9
|
+
author="Volkan Tasci",
|
|
10
|
+
author_email="volkantasci@gmail.com",
|
|
11
|
+
description="A professional Python client library for the Teable API",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/volkantasci/teable-client",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.7",
|
|
23
|
+
"Programming Language :: Python :: 3.8",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
],
|
|
28
|
+
python_requires=">=3.7",
|
|
29
|
+
install_requires=[
|
|
30
|
+
"requests>=2.25.0",
|
|
31
|
+
"python-dateutil>=2.8.0",
|
|
32
|
+
"typing-extensions>=4.0.0",
|
|
33
|
+
],
|
|
34
|
+
extras_require={
|
|
35
|
+
"dev": [
|
|
36
|
+
"pytest>=6.0.0",
|
|
37
|
+
"pytest-cov>=2.0.0",
|
|
38
|
+
"black>=21.0.0",
|
|
39
|
+
"isort>=5.0.0",
|
|
40
|
+
"mypy>=0.900",
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Teable Client Library
|
|
3
|
+
|
|
4
|
+
A professional Python client library for interacting with the Teable API.
|
|
5
|
+
Provides an object-oriented interface for managing tables, records, fields, and views.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "1.0.0"
|
|
9
|
+
|
|
10
|
+
from .core.client import TeableClient
|
|
11
|
+
from .exceptions import (
|
|
12
|
+
TeableError,
|
|
13
|
+
APIError,
|
|
14
|
+
AuthenticationError,
|
|
15
|
+
BatchOperationError,
|
|
16
|
+
ConfigurationError,
|
|
17
|
+
NetworkError,
|
|
18
|
+
RateLimitError,
|
|
19
|
+
ResourceNotFoundError,
|
|
20
|
+
ValidationError
|
|
21
|
+
)
|
|
22
|
+
from .models.config import TeableConfig
|
|
23
|
+
from .models.field import Field, FieldType
|
|
24
|
+
from .models.record import Record, RecordBatch
|
|
25
|
+
from .models.table import Table
|
|
26
|
+
from .models.view import (
|
|
27
|
+
View,
|
|
28
|
+
QueryBuilder,
|
|
29
|
+
FilterOperator,
|
|
30
|
+
SortDirection,
|
|
31
|
+
FilterCondition,
|
|
32
|
+
SortCondition
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
# Core
|
|
37
|
+
'TeableClient',
|
|
38
|
+
'TeableConfig',
|
|
39
|
+
|
|
40
|
+
# Models
|
|
41
|
+
'Table',
|
|
42
|
+
'Record',
|
|
43
|
+
'RecordBatch',
|
|
44
|
+
'Field',
|
|
45
|
+
'FieldType',
|
|
46
|
+
'View',
|
|
47
|
+
'QueryBuilder',
|
|
48
|
+
'FilterOperator',
|
|
49
|
+
'SortDirection',
|
|
50
|
+
'FilterCondition',
|
|
51
|
+
'SortCondition',
|
|
52
|
+
|
|
53
|
+
# Exceptions
|
|
54
|
+
'TeableError',
|
|
55
|
+
'APIError',
|
|
56
|
+
'AuthenticationError',
|
|
57
|
+
'BatchOperationError',
|
|
58
|
+
'ConfigurationError',
|
|
59
|
+
'NetworkError',
|
|
60
|
+
'RateLimitError',
|
|
61
|
+
'ResourceNotFoundError',
|
|
62
|
+
'ValidationError',
|
|
63
|
+
|
|
64
|
+
# Version
|
|
65
|
+
'__version__'
|
|
66
|
+
]
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Teable Client Exceptions Module
|
|
3
|
+
|
|
4
|
+
This module defines the exception hierarchy used throughout the Teable client library.
|
|
5
|
+
All custom exceptions inherit from TeableError to allow for specific error handling.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TeableError(Exception):
|
|
12
|
+
"""Base exception class for all Teable-related errors."""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class APIError(TeableError):
|
|
17
|
+
"""
|
|
18
|
+
Exception raised when the Teable API returns an error response.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
message (str): Human-readable error description
|
|
22
|
+
status_code (Optional[int]): HTTP status code if available
|
|
23
|
+
response_body (Optional[str]): Raw response body if available
|
|
24
|
+
"""
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
message: str,
|
|
28
|
+
status_code: Optional[int] = None,
|
|
29
|
+
response_body: Optional[str] = None
|
|
30
|
+
):
|
|
31
|
+
self.status_code = status_code
|
|
32
|
+
self.response_body = response_body
|
|
33
|
+
super().__init__(message)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ValidationError(TeableError):
|
|
37
|
+
"""
|
|
38
|
+
Exception raised when data validation fails.
|
|
39
|
+
|
|
40
|
+
This could be due to:
|
|
41
|
+
- Invalid field types
|
|
42
|
+
- Missing required fields
|
|
43
|
+
- Value constraints violations
|
|
44
|
+
"""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ConfigurationError(TeableError):
|
|
49
|
+
"""
|
|
50
|
+
Exception raised when there are issues with client configuration.
|
|
51
|
+
|
|
52
|
+
This could be due to:
|
|
53
|
+
- Missing API credentials
|
|
54
|
+
- Invalid API URL
|
|
55
|
+
- Missing required configuration parameters
|
|
56
|
+
"""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class RateLimitError(APIError):
|
|
61
|
+
"""
|
|
62
|
+
Exception raised when API rate limits are exceeded.
|
|
63
|
+
|
|
64
|
+
Attributes:
|
|
65
|
+
reset_time (Optional[float]): Unix timestamp when the rate limit resets
|
|
66
|
+
limit (Optional[int]): The rate limit ceiling for the given endpoint
|
|
67
|
+
"""
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
message: str,
|
|
71
|
+
status_code: Optional[int] = 429,
|
|
72
|
+
reset_time: Optional[float] = None,
|
|
73
|
+
limit: Optional[int] = None
|
|
74
|
+
):
|
|
75
|
+
self.reset_time = reset_time
|
|
76
|
+
self.limit = limit
|
|
77
|
+
super().__init__(message, status_code)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class ResourceNotFoundError(APIError):
|
|
81
|
+
"""
|
|
82
|
+
Exception raised when a requested resource is not found.
|
|
83
|
+
|
|
84
|
+
This could be due to:
|
|
85
|
+
- Invalid record ID
|
|
86
|
+
- Invalid table ID
|
|
87
|
+
- Invalid view ID
|
|
88
|
+
- Invalid field ID
|
|
89
|
+
"""
|
|
90
|
+
def __init__(
|
|
91
|
+
self,
|
|
92
|
+
message: str,
|
|
93
|
+
resource_type: str,
|
|
94
|
+
resource_id: str,
|
|
95
|
+
status_code: Optional[int] = 404
|
|
96
|
+
):
|
|
97
|
+
self.resource_type = resource_type
|
|
98
|
+
self.resource_id = resource_id
|
|
99
|
+
super().__init__(
|
|
100
|
+
f"{message} ({resource_type}: {resource_id})",
|
|
101
|
+
status_code
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class AuthenticationError(APIError):
|
|
106
|
+
"""
|
|
107
|
+
Exception raised when authentication fails.
|
|
108
|
+
|
|
109
|
+
This could be due to:
|
|
110
|
+
- Invalid API key
|
|
111
|
+
- Expired credentials
|
|
112
|
+
- Insufficient permissions
|
|
113
|
+
"""
|
|
114
|
+
def __init__(self, message: str, status_code: Optional[int] = 401):
|
|
115
|
+
super().__init__(message, status_code)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class NetworkError(TeableError):
|
|
119
|
+
"""
|
|
120
|
+
Exception raised when network-related issues occur.
|
|
121
|
+
|
|
122
|
+
This could be due to:
|
|
123
|
+
- Connection timeouts
|
|
124
|
+
- DNS resolution failures
|
|
125
|
+
- SSL/TLS errors
|
|
126
|
+
"""
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class BatchOperationError(TeableError):
|
|
131
|
+
"""
|
|
132
|
+
Exception raised when a batch operation partially fails.
|
|
133
|
+
|
|
134
|
+
Attributes:
|
|
135
|
+
successful_operations (list): List of successfully processed items
|
|
136
|
+
failed_operations (list): List of failed operations with their errors
|
|
137
|
+
"""
|
|
138
|
+
def __init__(
|
|
139
|
+
self,
|
|
140
|
+
message: str,
|
|
141
|
+
successful_operations: list,
|
|
142
|
+
failed_operations: list
|
|
143
|
+
):
|
|
144
|
+
self.successful_operations = successful_operations
|
|
145
|
+
self.failed_operations = failed_operations
|
|
146
|
+
super().__init__(message)
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: teable-client
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A professional Python client library for the Teable API
|
|
5
|
+
Home-page: https://github.com/volkantasci/teable-client
|
|
6
|
+
Author: Volkan Tasci
|
|
7
|
+
Author-email: volkantasci@gmail.com
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.7
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: requests>=2.25.0
|
|
22
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
23
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=6.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-cov>=2.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: black>=21.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: isort>=5.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: mypy>=0.900; extra == "dev"
|
|
30
|
+
Dynamic: author
|
|
31
|
+
Dynamic: author-email
|
|
32
|
+
Dynamic: classifier
|
|
33
|
+
Dynamic: description
|
|
34
|
+
Dynamic: description-content-type
|
|
35
|
+
Dynamic: home-page
|
|
36
|
+
Dynamic: provides-extra
|
|
37
|
+
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
40
|
+
|
|
41
|
+
# Teable Client Library
|
|
42
|
+
|
|
43
|
+
A professional Python client library for interacting with the Teable API. This library provides an object-oriented interface for managing tables, records, fields, and views in Teable.
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- Full Teable API coverage with an intuitive object-oriented interface
|
|
48
|
+
- Comprehensive field type support with validation
|
|
49
|
+
- Efficient batch operations for creating, updating, and deleting records
|
|
50
|
+
- Advanced querying capabilities with a fluent query builder
|
|
51
|
+
- Automatic rate limiting and retry handling
|
|
52
|
+
- Resource caching for improved performance
|
|
53
|
+
- Type hints for better IDE support
|
|
54
|
+
- Detailed documentation and examples
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
You can install the package using pip:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install teable-client
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from teable import TeableClient, TeableConfig
|
|
68
|
+
|
|
69
|
+
# Initialize the client
|
|
70
|
+
config = TeableConfig(
|
|
71
|
+
api_url="https://your-teable-instance.com/api",
|
|
72
|
+
api_key="your-api-key"
|
|
73
|
+
)
|
|
74
|
+
client = TeableClient(config)
|
|
75
|
+
|
|
76
|
+
# Get a table
|
|
77
|
+
table = client.get_table("table_id")
|
|
78
|
+
|
|
79
|
+
# Create a record
|
|
80
|
+
record = table.create_record({
|
|
81
|
+
"name": "John Doe",
|
|
82
|
+
"email": "john@example.com",
|
|
83
|
+
"age": 30
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
# Query records
|
|
87
|
+
query = table.query()\
|
|
88
|
+
.filter("age", ">", 25)\
|
|
89
|
+
.sort("name")\
|
|
90
|
+
.paginate(take=10)
|
|
91
|
+
|
|
92
|
+
records = table.get_records(query)
|
|
93
|
+
|
|
94
|
+
# Batch create records
|
|
95
|
+
records_data = [
|
|
96
|
+
{"name": "Alice", "age": 28},
|
|
97
|
+
{"name": "Bob", "age": 32}
|
|
98
|
+
]
|
|
99
|
+
batch_result = table.batch_create_records(records_data)
|
|
100
|
+
print(f"Created {batch_result.success_count} records")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Advanced Usage
|
|
104
|
+
|
|
105
|
+
### Working with Fields
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from teable import FieldType, Field
|
|
109
|
+
|
|
110
|
+
# Get table fields
|
|
111
|
+
fields = table.fields
|
|
112
|
+
|
|
113
|
+
# Access field properties
|
|
114
|
+
for field in fields:
|
|
115
|
+
print(f"{field.name} ({field.field_type})")
|
|
116
|
+
if field.is_required:
|
|
117
|
+
print(" Required field")
|
|
118
|
+
if field.is_primary:
|
|
119
|
+
print(" Primary field")
|
|
120
|
+
|
|
121
|
+
# Validate field values
|
|
122
|
+
field = table.get_field("field_id")
|
|
123
|
+
try:
|
|
124
|
+
field.validate_value(some_value)
|
|
125
|
+
except ValidationError as e:
|
|
126
|
+
print(f"Invalid value: {e}")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Using Views
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
# Get table views
|
|
133
|
+
views = table.views
|
|
134
|
+
|
|
135
|
+
# Get records from a specific view
|
|
136
|
+
view = table.get_view("view_id")
|
|
137
|
+
query = view.create_query().paginate(take=20)
|
|
138
|
+
records = table.get_records(query)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Advanced Querying
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from teable import FilterOperator, SortDirection
|
|
145
|
+
|
|
146
|
+
# Complex query with multiple conditions
|
|
147
|
+
query = table.query()\
|
|
148
|
+
.filter("status", FilterOperator.EQUALS, "active")\
|
|
149
|
+
.filter("age", FilterOperator.GREATER_THAN, 25)\
|
|
150
|
+
.filter("tags", FilterOperator.CONTAINS, "important")\
|
|
151
|
+
.sort("created_time", SortDirection.DESCENDING)\
|
|
152
|
+
.sort("priority")\
|
|
153
|
+
.search("urgent", field="title")\
|
|
154
|
+
.paginate(take=50, skip=100)
|
|
155
|
+
|
|
156
|
+
records = table.get_records(query)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Batch Operations
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
# Batch create
|
|
163
|
+
records_data = [
|
|
164
|
+
{"name": "Alice", "department": "Engineering"},
|
|
165
|
+
{"name": "Bob", "department": "Marketing"}
|
|
166
|
+
]
|
|
167
|
+
batch_result = table.batch_create_records(records_data)
|
|
168
|
+
|
|
169
|
+
print(f"Successfully created: {batch_result.success_count}")
|
|
170
|
+
if batch_result.failed:
|
|
171
|
+
print("Failed operations:")
|
|
172
|
+
for failure in batch_result.failed:
|
|
173
|
+
print(f" {failure}")
|
|
174
|
+
|
|
175
|
+
# Batch update
|
|
176
|
+
updates = [
|
|
177
|
+
{"id": "rec1", "fields": {"status": "completed"}},
|
|
178
|
+
{"id": "rec2", "fields": {"status": "completed"}}
|
|
179
|
+
]
|
|
180
|
+
table.batch_update_records(updates)
|
|
181
|
+
|
|
182
|
+
# Batch delete
|
|
183
|
+
record_ids = ["rec1", "rec2", "rec3"]
|
|
184
|
+
table.batch_delete_records(record_ids)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Error Handling
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from teable import (
|
|
191
|
+
TeableError,
|
|
192
|
+
APIError,
|
|
193
|
+
ValidationError,
|
|
194
|
+
ResourceNotFoundError
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
try:
|
|
198
|
+
record = table.get_record("invalid_id")
|
|
199
|
+
except ResourceNotFoundError as e:
|
|
200
|
+
print(f"Record not found: {e}")
|
|
201
|
+
except ValidationError as e:
|
|
202
|
+
print(f"Validation error: {e}")
|
|
203
|
+
except APIError as e:
|
|
204
|
+
print(f"API error {e.status_code}: {e}")
|
|
205
|
+
except TeableError as e:
|
|
206
|
+
print(f"Other error: {e}")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Configuration Options
|
|
210
|
+
|
|
211
|
+
The `TeableConfig` class supports various options to customize the client behavior:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
config = TeableConfig(
|
|
215
|
+
api_url="https://your-teable-instance.com/api",
|
|
216
|
+
api_key="your-api-key",
|
|
217
|
+
timeout=30.0, # Request timeout in seconds
|
|
218
|
+
max_retries=3, # Maximum number of retry attempts
|
|
219
|
+
retry_delay=1.0, # Delay between retries in seconds
|
|
220
|
+
default_table_id=None, # Default table ID for operations
|
|
221
|
+
default_view_id=None # Default view ID for operations
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
To set up the development environment:
|
|
228
|
+
|
|
229
|
+
1. Clone the repository
|
|
230
|
+
2. Install development dependencies:
|
|
231
|
+
```bash
|
|
232
|
+
pip install -e ".[dev]"
|
|
233
|
+
```
|
|
234
|
+
3. Run tests:
|
|
235
|
+
```bash
|
|
236
|
+
pytest
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Contributing
|
|
240
|
+
|
|
241
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
242
|
+
|
|
243
|
+
## License
|
|
244
|
+
|
|
245
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
teable/__init__.py
|
|
5
|
+
teable/exceptions/__init__.py
|
|
6
|
+
teable_client.egg-info/PKG-INFO
|
|
7
|
+
teable_client.egg-info/SOURCES.txt
|
|
8
|
+
teable_client.egg-info/dependency_links.txt
|
|
9
|
+
teable_client.egg-info/requires.txt
|
|
10
|
+
teable_client.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
teable
|