Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
1c282ef
removed synchronous code
lfparis Sep 19, 2020
7141dc9
Merge pull request #1 from lfparis/init-release
lfparis Sep 19, 2020
2609823
added download_url
lfparis Sep 19, 2020
a344193
updated README & name
lfparis Sep 19, 2020
aeecb05
udpated description
lfparis Sep 19, 2020
7059971
updated download url
lfparis Sep 19, 2020
0192011
updated download url
lfparis Sep 19, 2020
70e11da
updated typing
lfparis Sep 19, 2020
279ca0a
updated download url
lfparis Sep 19, 2020
fc90bfd
updated version number
lfparis Sep 19, 2020
3391d55
initial setup
lfparis Sep 19, 2020
82ac61c
initial setup
lfparis Sep 19, 2020
6573bef
testing WIP
lfparis Sep 20, 2020
053fe8c
Added utils to setup
lfparis Sep 20, 2020
cb3fc50
Added utils to setup
lfparis Sep 20, 2020
d7a9427
first test
lfparis Sep 20, 2020
cb2f462
added ci status + pypi downloads
lfparis Sep 20, 2020
c844aef
added ci status + pypi downloads
lfparis Sep 20, 2020
3594402
cleaned first test
lfparis Sep 21, 2020
740cf4f
cleaned first test
lfparis Sep 21, 2020
2ac43e5
cleanup
lfparis Sep 21, 2020
9dadd12
added coveralls
lfparis Sep 21, 2020
14caa0c
changed --line-length 79
lfparis Sep 21, 2020
32ff9f9
test test
lfparis Sep 21, 2020
7efa927
updated badges
lfparis Sep 21, 2020
a6dabb7
Merge branch 'master' into integrate-testing
lfparis Sep 21, 2020
24a21f8
Merge pull request #2 from lfparis/integrate-testing
lfparis Sep 21, 2020
8060476
added python badges
lfparis Sep 21, 2020
9718ceb
added pytest-asyncio
lfparis Sep 21, 2020
16f318f
added api_key test
lfparis Sep 21, 2020
46815a6
added server.connect
lfparis Sep 21, 2020
8b46c3b
passenv = LANG
lfparis Sep 21, 2020
3ea3f89
passenv mod
lfparis Sep 21, 2020
2d9b50e
updated tests
lfparis Sep 21, 2020
2e01fc0
Merge pull request #3 from lfparis/new-tests
lfparis Sep 21, 2020
b70f978
added Airtable.get_table()
lfparis Sep 21, 2020
4639909
updated version number
lfparis Sep 21, 2020
748f276
added attachment comparison
lfparis Sep 22, 2020
7afc055
minor fix to get table
lfparis Sep 22, 2020
708b483
updated version
lfparis Sep 22, 2020
ac3ccc2
minor update to usage
lfparis Sep 22, 2020
da9a4d7
Added Index Error
lfparis Sep 25, 2020
d5685ae
added typing and kwargs to get_base and get_table
lfparis Sep 25, 2020
f95898e
Handle cases with no response
cancan101 Nov 13, 2020
c05cf8e
Make package PEP 561 compatible
cancan101 Nov 13, 2020
7bd3861
make pandas an optional install (using tools)
cancan101 Nov 13, 2020
7814b35
Simplify python_requires line
cancan101 Nov 13, 2020
87ce29f
Merge pull request #4 from cancan101/patch-1
lfparis Nov 26, 2020
b307bb3
Merge pull request #6 from cancan101/pep-561
lfparis Nov 26, 2020
11012e1
Merge branch 'master' into install/pandas-optional
lfparis Nov 26, 2020
fe70480
Merge pull request #7 from cancan101/install/pandas-optional
lfparis Nov 26, 2020
cb2820e
Merge branch 'master' into patch-2
lfparis Nov 26, 2020
dd3a0f3
Merge pull request #8 from cancan101/patch-2
lfparis Nov 26, 2020
481f04b
No server calls for known base ids or table names
lfparis Nov 26, 2020
29fe959
added first todos
lfparis Nov 26, 2020
a4b600e
updated version
lfparis Nov 26, 2020
f4f4e71
_request exponential retries simplified
lfparis Nov 30, 2020
5bd6af6
0.0.1b7
lfparis Nov 30, 2020
aa98b98
added semaphore todo
lfparis Nov 30, 2020
14d49d4
added timeout to Airtable constructor
lfparis Dec 10, 2020
bac67e6
direnv update
lfparis Jan 18, 2021
7a9e4e2
Merge pull request #11 from lfparis/get-options
lfparis Jan 18, 2021
f5b195e
added typecast option
lfparis Mar 2, 2021
552d057
ignore venv
lfparis Mar 2, 2021
b14188e
Merge pull request #12 from lfparis/typecast
lfparis Mar 2, 2021
544c516
version 1b9
lfparis Mar 2, 2021
dc6a714
added raise_for_status and record validation
lfparis Sep 8, 2021
5fec83f
added logging or raise method
lfparis Sep 8, 2021
4f84e68
Merge pull request #15 from lfparis/0.0.1b10
lfparis Sep 8, 2021
a9e4c44
updated version info
lfparis Sep 8, 2021
a7cc3a8
added better logging, response status codes to error messages & retur…
lfparis Jun 17, 2022
afc92fe
added support for Airtable classes to be used outside with block
lfparis Jun 17, 2022
30e82ed
updated setup and metadata
lfparis Jun 17, 2022
10ca32f
logging cleanup WIP
lfparis Jun 17, 2022
fac03d8
simplified record request methods and added typing
lfparis Jun 20, 2022
9edd744
reverted requirements structure
lfparis Jun 20, 2022
0eb4f38
Merge pull request #22 from lfparis/q2_2022_updates
lfparis Jun 20, 2022
813ff53
modified raise_or_log_error() to process from ClientResponse
lfparis Jun 21, 2022
bccd0f7
added AirbaseResponseException() and updated raise_or_log_error()
lfparis Jun 21, 2022
3d4e191
added AirbaseResponseException() and updated raise_or_log_error()
lfparis Jun 21, 2022
d383239
code cleanup and new pre-release-version
lfparis Jun 28, 2022
1030c20
Merge pull request #23 from lfparis/error_logging_improvements
lfparis Jun 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true

# Matches the exact files either package.json or .travis.yml
[*.yml]
indent_style = space
indent_size = 2
7 changes: 7 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Adds the bin directory to the environment
PATH_add bin

# Source the necessary environment for all users
set -o allexport
source .env
set +o allexport
16 changes: 13 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
build/
dist/
docs/build

.DS_store
.eggs
.tox
Expand All @@ -6,7 +10,13 @@
*.pyc
.pytest_cache
.mypy_cache\
.env
.cache
*.todo
mypy.ini
coverage.xml
.coverage

.env
.vscode
.venv
.python-version

test.py
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
dist: bionic
language: python
git:
depth: 2
python:
- "3.7"
- "3.8"
matrix:
include:
python: "3.7"
env: TOXENV=lint
install:
- pip install .
- pip install tox tox-travis
script: tox
after_success:
- pip install pytest pytest-asyncio aiohttp coveralls
- coverage run --source=airbase setup.py test
- coveralls
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 Luis Felipe Paris
Copyright (c) 2022 Luis Felipe Paris

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include LICENSE
include README.md
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Colours
NC=\033[0m\n
HIGHLIGHT=\033[91m

## usage: print useful commands
usage:
@echo "$(HIGHLIGHT)Choose a command: $(PWD) $(NC)"
@bash -c "sed -ne 's/^##//p' ./Makefile | column -t -s ':' | sed -e 's/^/ /'"

## release: Release new version
release:
python setup.py sdist bdist_wheel --universal
twine upload ./dist/*
make clean

## test: Run tests
test:
tox
make clean

## lint: Lint and format
lint:
flake8 .
black --line-length 79 --check .

## clean: delete python artifacts
clean:
python -c "import pathlib; [p.unlink() for p in pathlib.Path('.').rglob('*.py[co]')]"
python -c "import pathlib; [p.rmdir() for p in pathlib.Path('.').rglob('pytest_cache')]"
rm -rdf ./dist
rm -rdf ./build
rm -rdf airbase.egg-info
153 changes: 27 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
# Airtable Python Wrapper
# Asynchronous Airtable Python Wrapper
[![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370)
[![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-380)

[![PyPI version](https://badge.fury.io/py/airtable-async.svg)](https://badge.fury.io/py/airtable-async)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/airtable-async.svg?label=pypi%20downloads)](https://pypi.org/project/airtable-async/)
[![Build Status](https://travis-ci.org/lfparis/airbase.svg?branch=master)](https://travis-ci.org/lfparis/airbase)
[![Coverage Status](https://coveralls.io/repos/github/lfparis/airbase/badge.svg?branch=master)](https://coveralls.io/github/lfparis/airbase?branch=master)

## Installing
```bash
pip install airtable-async
```
Requirements: Python 3.7+

## Documentation
*coming soon*

## Example

### Asynchronous
Requires CPython 3.8
```python
import asyncio
from airbase import AirtableAsync as Airtable
from airbase import Airtable

api_key = "your Airtable API key found at https://airtable.com/account"
base_key = "name or id of a base"
Expand All @@ -13,6 +29,7 @@ table_key = "name or id of a table in that base"

async def main() -> None:
async with Airtable(api_key=api_key) as at:
at: Airtable

# Get all bases for a user
await at.get_bases()
Expand Down Expand Up @@ -83,7 +100,7 @@ async def main() -> None:
"id": "record id",
"fields": {"field1": "value1", "field2": "value2"},
}
await table.update_record()
await table.update_record(record)
# Update several records in that table
records = [
{
Expand All @@ -99,142 +116,26 @@ async def main() -> None:
"fields": {"field1": "value1", "field2": "value2"},
},
]
await table.update_records()
await table.update_records(records)

# Delete a record in that table
record = {
"id": "record id",
}
await table.delete_record()
await table.delete_record(record)
# Delete several records in that table
records = [
{"id": "record id"},
{"id": "record id"},
{"id": "record id"},
]
await table.delete_records()
await table.delete_records(records)


if __name__ == "__main__":
asyncio.run(main())
```

### Synchronous
Works in ironpython and cpython 2.7 and beyond
```python
from airbase import Airtable

api_key = "your Airtable API key found at https://airtable.com/account"
base_key = "id of a base"
table_key = "name of a table in that base"


def main() -> None:
# NOT IMPLEMENTED - with Airtable(api_key=api_key) as at:
at = Airtable(api_key=api_key)

# Get all bases for a user
at.get_bases()

# NOT IMPLEMENTED - Get one base by name
# base = at.get_base(base_key, key="name")
# Get one base by id
base = at.get_base(base_key)
# NOT IMPLEMENTED - Get one base by either id or name
# base = at.get_base(base_key)

# Base Attributes
print(base.id)
print(base.name)
print(base.permission_level)

# Set base logging level (debug, info, warning, error, etc)
# Default is "info"
base.log = "debug"

# Get all tables for a base
base.get_tables()

# Get one table by name
table = base.get_table(table_key)
# NOT IMPLEMENTED - Get one table by id
# table = at.get_table(table_key, key="id")
# NOT IMPLEMENTED - Get one table by either id or name
# table = at.get_table(table_key)

# Base Attributes
print(table.base)
print(table.name)
print(table.id)
print(table.primary_field_id)
# print(table.primary_field_name)
print(table.fields)
print(table.views)

# Get a record in that table
table_record = table.get_record("record_id")
# Get all records in that table
table_records = table.get_records()
# NOT IMPLEMENTED - Get all records in a view in that table
# view_records = table.get_records(view="view id or name")
# Get only certain fields for all records in that table
reduced_fields_records = table.get_records(
filter_by_fields=["field1, field2"]
)
# Get all records in that table that pass a formula
filtered_records = table.get_records(
filter_by_formula="Airtable Formula"
)

# Post a record in that table
record = {"fields": {"field1": "value1", "field2": "value2"}}
table.post_record(record)
# Post several records in that table
records = [
{"fields": {"field1": "value1", "field2": "value2"}},
{"fields": {"field1": "value1", "field2": "value2"}},
{"fields": {"field1": "value1", "field2": "value2"}},
]
table.post_records(records)

# Update a record in that table
record = {
"id": "record id",
"fields": {"field1": "value1", "field2": "value2"},
}
table.update_record()
# Update several records in that table
records = [
{
"id": "record id",
"fields": {"field1": "value1", "field2": "value2"},
},
{
"id": "record id",
"fields": {"field1": "value1", "field2": "value2"},
},
{
"id": "record id",
"fields": {"field1": "value1", "field2": "value2"},
},
]
table.update_records()

# Delete a record in that table
record = {
"id": "record id",
}
table.delete_record()
# NOT IMPLEMENTED - Delete several records in that table
# records = [
# {"id": "record id"},
# {"id": "record id"},
# {"id": "record id"},
# ]
# table.delete_records()


if __name__ == "__main__":
main()
## License

```
[MIT](https://opensource.org/licenses/MIT)
1 change: 0 additions & 1 deletion airbase/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from __future__ import absolute_import
from .airtable import Airtable # noqa: F401
from .airtable_async import Airtable as AirtableAsync # noqa: F401
Loading