Giter Club home page Giter Club logo

airbase's People

Contributors

cancan101 avatar lfparis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

airbase's Issues

Return new record on table insert

Airtable's API returns newly created records by default. It would be nice to have access to that response. At the moment, post_record and post_records returns boolean.

About logger info

Hello! Thanks for the aysnc of airtable.
I tried and found that even I setup as base.log = "error" the logger will still show up on cmd (such as (airbase.airtable): INFO - Fetched 2 records)
Is it have any way can disable it?
And also if possible adding sort will be great! Thanks!

No option to use sort when using get_records function

The library is not bad, but there is no way to use sorting, as airtable writes the order of records without using sorting will be arbitrary, which is true and a big nuance for those who want to further save data from any beginning, sorting by date to the end, and then using slices to receive for example only 1200 records from the table.

Can you please tell me when you will add this feature?

Error in delete row

When I run this code from example:

record = {"id": "recID",}
await table.delete_record(record)

Raises an Error

Traceback (most recent call last):
  File "airtable/table.py", line 128, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "airtable/table.py", line 124, in main
    await table.delete_record(record)
  File "/hdd/gh/zhurbot/venv/lib/python3.8/site-packages/airbase/airtable.py", line 595, in delete_record
    message = record["fields"].get(self.primary_field_name) or record.get(
KeyError: 'fields'

I've read the code and modified the record:

record = {'fields': {'id': 'recID'}, 'id': 'recID'}
await table.delete_record(record)

2021-08-27 13:41:38 (UTC/GMT +0300) (airbase.airtable): INFO - Deleted: recID

May be smth wrong with code?

➜ pip freeze
aiogram==2.14.3
aiohttp==3.7.4.post0
aiosqlite==0.17.0
airtable-async==0.0.1b9
async-timeout==3.0.1
attrs==21.2.0
Babel==2.9.1
certifi==2021.5.30
chardet==4.0.0
charset-normalizer==2.0.4
idna==3.2
multidict==5.1.0
pyairtable==1.0.0
pytz==2021.1
requests==2.26.0
typing-extensions==3.10.0.0
urllib3==1.26.6
yarl==1.6.3

➜ python -V
Python 3.8.10

➜ pip --version
pip 21.1.3 from /hdd/gh/zhurbot/venv/lib/python3.8/site-packages/pip (python 3.8)

If you need some more info, I'll send

Remove requirement on `async with Airtable()`

At the moment, it looks like the only way to make requests to Airtable is to make requests inside an async with Airtable() block. That is because the session is open only inside Airtable's async with. Thus, a Table.get_record() only works within that block. While this works well, it would also be nice to create an instance of Airtable, Base, and Table and be able to reuse it, and that it would keep a session open. I can't even do an async with Table, as it inherits from BaseAirtable.

A simple solution would be to open and close a session at every request if one is not open. This would at least make the library more flexible to use. Another solution would be that each instance would keep its own session open.

What do you think about this?
Was it a deliberate intention that every request to Airtable needs to be inside the async with Airtable block?

Odd implementation for exponential backoff

Looking at:

await asyncio.sleep(0.1 * count ** 2)

I think you want something like:

delay = (count ** 2) * 0.1

ie a doubling (multiplicative) increase each iteration.
and then ideally count increments by 1 each iteration to make code more understandable.

Also with the current default settings of retries, you do get a pretty long delay on the function call.

No way to tell if get_records ran into an error

Currently if get_records hit an error, a warning is logged out; however, the caller of this method cannot then tell that the results set returned is incomplete:

airbase/airbase/airtable.py

Lines 424 to 426 in 544c516

if not self._is_success(res):
logger.warning(f"Table: {self.name} could not be retreived.")
break

Assuming we do not want to change the return signature of the method, two solutions come to mind:

  1. Just raise an exception rather than printing a warning. This can be combined with option 2 where the raising an error (vs warning) is controlled by a parameter.
  2. An additional parameter that does change the return value to include some status information
  3. An error flag that is set on the Table class and is cleared before get_records is run and that contains various information

Better Handling of Error Codes from Airtable API

Now with #13 (comment), airbase has the option to raise exceptions when an error is received from the Airtable API. There are currently two issues with the current implementation.

  1. The raised error does not indicate to the user which error response code was received from Airtable
  2. The full set of "transient errors" (in which is a retry is appropriate) is not handled

Problem 1 can be addressed by passing the response / response code to raise_or_log_error (when it exists) and attaching that to the AirbaseException or the log statement.

Problem 2 can be solved by adding to the list found here to include more of the transient errors listed at: https://support.airtable.com/hc/en-us/articles/4403485509143-API-Common-troubleshooting: 500 and 502.

From my API docs I do see a few other 4XXs listed that are not on the previous page:
image
(such as 404 and 413); however, those are client errors and not transient.

I don't see 408 listed in either doc.

As an alternative to the above proposed solution to problem 1, different errors could be raised for transient errors (eg 500 or timeouts), from config errors (401/403) from payload errors (422).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.