Skip to content

Commit

Permalink
Run Black on everything (#1778)
Browse files Browse the repository at this point in the history
This is a follow-up to #1777 which runs Black on all our Python code, and ensures during CI that everything is formatted with Black.
  • Loading branch information
toolness authored Dec 2, 2020
1 parent 1e32992 commit 14844d5
Show file tree
Hide file tree
Showing 423 changed files with 9,735 additions and 9,996 deletions.
5 changes: 1 addition & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ jobs:
yarn build
yarn lint
yarn lingui:extract-and-check
# TODO: Once we've formatted all our code with Black, uncomment this line.
# pipenv run "black" --check .
pipenv run "black" --check .
pipenv run "flake8"
pipenv run "mypy" .
test:
Expand Down
1 change: 0 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ ignore =
# Disable "line break before binary operator"; seems to have been
# introduced in a very recent version of flake8 and we don't care.
W503
W504
# Black says we should ignore this one:
# https://black.readthedocs.io/en/stable/compatible_configs.html#flake8
E203
Expand Down
105 changes: 56 additions & 49 deletions airtable/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,20 @@
RATE_LIMIT_TIMEOUT_SECS = 30


def retry_request(method: str, url: str, max_retries: int, headers: Dict[str, str],
**kwargs) -> requests.Response:
'''
def retry_request(
method: str, url: str, max_retries: int, headers: Dict[str, str], **kwargs
) -> requests.Response:
"""
This wraps requests.request() but has built-in retry logic for when Airtable's
rate limit is exceeded (up to a maximum number of retries).
'''
"""

attempts = 0

while True:
res = req_session.request(
method, url, headers=headers, timeout=settings.AIRTABLE_TIMEOUT, **kwargs)
method, url, headers=headers, timeout=settings.AIRTABLE_TIMEOUT, **kwargs
)
attempts += 1
if attempts <= max_retries and res.status_code == RATE_LIMIT_EXCEEDED:
time.sleep(RATE_LIMIT_TIMEOUT_SECS)
Expand All @@ -58,9 +60,9 @@ def retry_request(method: str, url: str, max_retries: int, headers: Dict[str, st


class Airtable:
'''
"""
This class encapsulates the Airtable API.
'''
"""

# The base URL endpoint for the Airtable, e.g.
# "https://api.airtable.com/v0/appEH2XUPhLwkrS66/Users".
Expand All @@ -73,30 +75,36 @@ class Airtable:
# rate limiting. If this is 0, then no retries will be attempted.
max_retries: int

def __init__(self, url: Optional[str] = None, api_key: Optional[str] = None,
max_retries: int = 0) -> None:
def __init__(
self, url: Optional[str] = None, api_key: Optional[str] = None, max_retries: int = 0
) -> None:
self.url = url or settings.AIRTABLE_URL
self.api_key = api_key or settings.AIRTABLE_API_KEY
self.max_retries = max_retries
if not (self.url and self.api_key):
raise ValueError('Configuration not provided, and Django settings not configured')

def request(self, method: str, pathname: Optional[str] = None, data: Optional[dict] = None,
params: Optional[Dict[str, str]] = None) -> requests.Response:
'''
raise ValueError("Configuration not provided, and Django settings not configured")

def request(
self,
method: str,
pathname: Optional[str] = None,
data: Optional[dict] = None,
params: Optional[Dict[str, str]] = None,
) -> requests.Response:
"""
This wraps requests.request(), appending the given optional pathname to the
base Airtable URL and sending the given optional data as JSON.
Authorization credentials are automatically included in the request, and an
exception is automatically raised if the request returns an error status code.
'''
"""

url = self.url if pathname is None else f"{self.url}/{pathname}"
kwargs: Dict[str, Any] = {'params': params}
headers = {'Authorization': f'Bearer {self.api_key}'}
kwargs: Dict[str, Any] = {"params": params}
headers = {"Authorization": f"Bearer {self.api_key}"}
if data is not None:
kwargs['data'] = json.dumps(data)
headers['Content-Type'] = 'application/json'
kwargs["data"] = json.dumps(data)
headers["Content-Type"] = "application/json"
res = retry_request(method, url, max_retries=self.max_retries, headers=headers, **kwargs)
if res.status_code == UNPROCESSABLE_ENTITY:
logger.error(
Expand All @@ -108,11 +116,11 @@ def request(self, method: str, pathname: Optional[str] = None, data: Optional[di
return res

def create_or_update(self, fields: Fields) -> Record:
'''
"""
Given the fields, this checks to see if a row already exists with the
fields' primary key. If it does, the row will be updated; otherwise,
a new row will be created.
'''
"""

record = self.get(fields.pk)
if record is None:
Expand All @@ -121,58 +129,57 @@ def create_or_update(self, fields: Fields) -> Record:
return self.update(record, fields)

def update(self, record: Record, fields: Fields) -> Record:
'''
"""
Updates the given row in Airtable with the given fields.
'''
"""

res = self.request('PATCH', record.id, data={
"fields": fields.dict(by_alias=True)
})
res = self.request("PATCH", record.id, data={"fields": fields.dict(by_alias=True)})
return Record(**res.json())

def create(self, fields: Fields) -> Record:
'''
"""
Creates a new row in Airtable with the given fields.
'''
"""

res = self.request('POST', data={
"fields": fields.dict(by_alias=True)
})
res = self.request("POST", data={"fields": fields.dict(by_alias=True)})
return Record(**res.json())

def get(self, pk: int) -> Optional[Record]:
'''
"""
Attempts to retrieve the row in Airtable that has the given
primary key. If it doesn't exist, None is returned.
'''

res = self.request('GET', params={
'filterByFormula': f'pk={pk}',
'maxRecords': '1',
})
records = res.json()['records']
"""

res = self.request(
"GET",
params={
"filterByFormula": f"pk={pk}",
"maxRecords": "1",
},
)
records = res.json()["records"]
if records:
record = records[0]
return Record(**record)
return None

def _get_raw_list_page(self, page_size: int, offset: str) -> Tuple[List[RawRow], str]:
params = {
'pageSize': str(page_size),
"pageSize": str(page_size),
}
if offset:
params['offset'] = offset
res = self.request('GET', params=params)
params["offset"] = offset
res = self.request("GET", params=params)
result = res.json()
next_offset = result.get('offset', '')
return (result['records'], next_offset)
next_offset = result.get("offset", "")
return (result["records"], next_offset)

def list_raw(self, page_size=100) -> Iterator[RawRow]:
'''
"""
Iterate through all rows in the Airtable, but with raw dictionary data.
'''
"""

offset = ''
offset = ""

while True:
records, offset = self._get_raw_list_page(page_size, offset)
Expand All @@ -182,9 +189,9 @@ def list_raw(self, page_size=100) -> Iterator[RawRow]:
break

def list(self, page_size=100) -> Iterator[Record]:
'''
"""
Iterate through all rows in the Airtable.
'''
"""

for raw_record in self.list_raw(page_size):
yield Record(**raw_record)
10 changes: 5 additions & 5 deletions airtable/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@


def validate_settings():
'''
"""
Ensure that the Airtable-related settings are defined properly.
'''
"""

ensure_dependent_settings_are_nonempty(
'AIRTABLE_URL',
'AIRTABLE_API_KEY',
"AIRTABLE_URL",
"AIRTABLE_API_KEY",
)


class AirtableConfig(AppConfig):
name = 'airtable'
name = "airtable"

def ready(self):
validate_settings()
6 changes: 3 additions & 3 deletions airtable/management/commands/exampleairtablecsv.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

class Command(BaseCommand):
help = (
f'Print an example CSV file to stdout. This can then be imported '
f'into Airtable, though you will still want to change the field '
f'types as documented in {airtable.record.__file__}.'
f"Print an example CSV file to stdout. This can then be imported "
f"into Airtable, though you will still want to change the field "
f"types as documented in {airtable.record.__file__}."
)

def handle(self, *args, **options):
Expand Down
12 changes: 4 additions & 8 deletions airtable/management/commands/syncairtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,14 @@


class Command(BaseCommand):
help = (
'Synchronize all users with Airtable, retrying if the rate '
'limit is exceeded.'
)
help = "Synchronize all users with Airtable, retrying if the rate " "limit is exceeded."

def add_arguments(self, parser):
parser.add_argument('--dry-run', help="don't actually change Airtable",
action='store_true')
parser.add_argument("--dry-run", help="don't actually change Airtable", action="store_true")

def handle(self, *args, **options):
verbosity = int(options['verbosity'])
dry_run: bool = options['dry_run']
verbosity = int(options["verbosity"])
dry_run: bool = options["dry_run"]
if not settings.AIRTABLE_URL:
raise CommandError("AIRTABLE_URL must be configured.")

Expand Down
Loading

0 comments on commit 14844d5

Please sign in to comment.