Skip to content

Commit

Permalink
Black support for the Python codebase (#4297)
Browse files Browse the repository at this point in the history
* Apply black formatting

* Add auto formatting when committing to master

* Update CONTRIBUTING.md re. Black & Prettier
  • Loading branch information
arikfr authored Dec 11, 2019
1 parent 37a964c commit 2dff8b9
Show file tree
Hide file tree
Showing 210 changed files with 11,269 additions and 8,148 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Python Code Formatting (Black)

on:
push:
branches:
- master

jobs:
format:
runs-on: ubuntu-latest

container:
image: python:3.7.4-alpine

steps:
- uses: actions/checkout@v1
- name: Install Black
run: apk add gcc musl-dev && pip install black
- name: Run Black
run: black redash tests migrations/versions
- name: Commit formatted code
uses: EndBug/[email protected]
with:
author_name: Black
author_email: [email protected]
message: "Autoformatted Python code with Black"
path: "."
pattern: "*.py"
force: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 7 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ When creating a new bug report, please make sure to:

If you would like to suggest an enhancement or ask for a new feature:

- Please check [the roadmap](https://trello.com/b/b2LUHU7A/redash-roadmap) for existing Trello card for what you want to suggest/ask. If there is, feel free to upvote it to signal interest or add your comments.
- If there is no existing card, open a thread in [the forum](https://discuss.redash.io/c/feature-requests) to start a discussion about what you want to suggest. Try to provide as much details and context as possible and include information about *the problem you want to solve* rather only *your proposed solution*.
- Please check [the forum](https://discuss.redash.io/c/feature-requests/5) for existing threads about what you want to suggest/ask. If there is, feel free to upvote it to signal interest or add your comments.
- If there is no open thread, you're welcome to start one to have a discussion about what you want to suggest. Try to provide as much details and context as possible and include information about *the problem you want to solve* rather only *your proposed solution*.

### Pull Requests

- **Code contributions are welcomed**. For big changes or significant features, it's usually better to reach out first and discuss what you want to implement and how (we recommend reading: [Pull Request First](https://medium.com/practical-blend/pull-request-first-f6bb667a9b6#.ozlqxvj36)). This to make sure that what you want to implement is aligned with our goals for the project and that no one else is already working on it.
- Include screenshots and animated GIFs in your pull request whenever possible.
- Please add [documentation](#documentation) for new features or changes in functionality along with the code.
- Please follow existing code style:
- Python: we use PEP8 for Python.
- Javascript: we use Airbnb's style guides for [JavaScript](https://github.com/airbnb/javascript#naming-conventions) and [React](https://github.com/airbnb/javascript/blob/master/react) (currently we don't follow Airbnb's convention for naming files, but we're gradually fixing this). To make it automatic and easy, we recommend using [Prettier](https://github.com/prettier/prettier).

- Python: we use [Black](https://github.com/psf/black) to auto format the code.
- Javascript: we use [Prettier](https://github.com/prettier/prettier) to auto-format the code.
### Documentation

The project's documentation can be found at [https://redash.io/help/](https://redash.io/help/). The [documentation sources](https://github.com/getredash/website/tree/master/src/pages/kb) are hosted on GitHub. To contribute edits / new pages, you can use GitHub's interface. Click the "Edit on GitHub" link on the documentation page to quickly open the edit interface.
Expand All @@ -66,9 +66,9 @@ The project's documentation can be found at [https://redash.io/help/](https://re

### Release Method

We publish a stable release every ~2 months, although the goal is to get to a stable release every month. You can see the change log on [GitHub releases page](https://github.com/getredash/redash/releases).
We publish a stable release every ~3-4 months, although the goal is to get to a stable release every month.

Every build of the master branch updates the latest *RC release*. These releases are usually stable, but might contain regressions and therefore recommended for "advanced users" only.
Every build of the master branch updates the *redash/redash:preview* Docker Image. These releases are usually stable, but might contain regressions and therefore recommended for "advanced users" only.

When we release a new stable release, we also update the *latest* Docker image tag, the EC2 AMIs and GCE images.

Expand Down
8 changes: 4 additions & 4 deletions migrations/versions/0f740a081d20_inline_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@


# revision identifiers, used by Alembic.
revision = '0f740a081d20'
down_revision = 'a92d92aa678e'
revision = "0f740a081d20"
down_revision = "a92d92aa678e"
branch_labels = None
depends_on = None


def upgrade():
tags_regex = re.compile('^([\w\s]+):|#([\w-]+)', re.I | re.U)
tags_regex = re.compile("^([\w\s]+):|#([\w-]+)", re.I | re.U)
connection = op.get_bind()

dashboards = connection.execute("SELECT id, name FROM dashboards")

update_query = text("UPDATE dashboards SET tags = :tags WHERE id = :id")

for dashboard in dashboards:
tags = compact(flatten(tags_regex.findall(dashboard[1])))
if tags:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@


# revision identifiers, used by Alembic.
revision = '1daa601d3ae5'
down_revision = '969126bd800f'
revision = "1daa601d3ae5"
down_revision = "969126bd800f"
branch_labels = None
depends_on = None


def upgrade():
op.add_column(
'users',
sa.Column('disabled_at', sa.DateTime(True), nullable=True)
)
op.add_column("users", sa.Column("disabled_at", sa.DateTime(True), nullable=True))


def downgrade():
op.drop_column('users', 'disabled_at')
op.drop_column("users", "disabled_at")
24 changes: 14 additions & 10 deletions migrations/versions/5ec5c84ba61e_.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,28 @@


# revision identifiers, used by Alembic.
revision = '5ec5c84ba61e'
down_revision = '7671dca4e604'
revision = "5ec5c84ba61e"
down_revision = "7671dca4e604"
branch_labels = None
depends_on = None


def upgrade():
conn = op.get_bind()
op.add_column('queries', sa.Column('search_vector', su.TSVectorType()))
op.create_index('ix_queries_search_vector', 'queries', ['search_vector'],
unique=False, postgresql_using='gin')
ss.sync_trigger(conn, 'queries', 'search_vector',
['name', 'description', 'query'])
op.add_column("queries", sa.Column("search_vector", su.TSVectorType()))
op.create_index(
"ix_queries_search_vector",
"queries",
["search_vector"],
unique=False,
postgresql_using="gin",
)
ss.sync_trigger(conn, "queries", "search_vector", ["name", "description", "query"])


def downgrade():
conn = op.get_bind()

ss.drop_trigger(conn, 'queries', 'search_vector')
op.drop_index('ix_queries_search_vector', table_name='queries')
op.drop_column('queries', 'search_vector')
ss.drop_trigger(conn, "queries", "search_vector")
op.drop_index("ix_queries_search_vector", table_name="queries")
op.drop_column("queries", "search_vector")
115 changes: 66 additions & 49 deletions migrations/versions/640888ce445d_.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,93 +15,110 @@


# revision identifiers, used by Alembic.
revision = '640888ce445d'
down_revision = '71477dadd6ef'
revision = "640888ce445d"
down_revision = "71477dadd6ef"
branch_labels = None
depends_on = None


def upgrade():
# Copy "schedule" column into "old_schedule" column
op.add_column('queries', sa.Column('old_schedule', sa.String(length=10), nullable=True))
op.add_column(
"queries", sa.Column("old_schedule", sa.String(length=10), nullable=True)
)

queries = table(
'queries',
sa.Column('schedule', sa.String(length=10)),
sa.Column('old_schedule', sa.String(length=10)))
"queries",
sa.Column("schedule", sa.String(length=10)),
sa.Column("old_schedule", sa.String(length=10)),
)

op.execute(
queries
.update()
.values({'old_schedule': queries.c.schedule}))
op.execute(queries.update().values({"old_schedule": queries.c.schedule}))

# Recreate "schedule" column as a dict type
op.drop_column('queries', 'schedule')
op.add_column('queries', sa.Column('schedule', MutableDict.as_mutable(PseudoJSON), nullable=False, server_default=json.dumps({})))
op.drop_column("queries", "schedule")
op.add_column(
"queries",
sa.Column(
"schedule",
MutableDict.as_mutable(PseudoJSON),
nullable=False,
server_default=json.dumps({}),
),
)

# Move over values from old_schedule
queries = table(
'queries',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('schedule', MutableDict.as_mutable(PseudoJSON)),
sa.Column('old_schedule', sa.String(length=10)))
"queries",
sa.Column("id", sa.Integer, primary_key=True),
sa.Column("schedule", MutableDict.as_mutable(PseudoJSON)),
sa.Column("old_schedule", sa.String(length=10)),
)

conn = op.get_bind()
for query in conn.execute(queries.select()):
schedule_json = {
'interval': None,
'until': None,
'day_of_week': None,
'time': None
"interval": None,
"until": None,
"day_of_week": None,
"time": None,
}

if query.old_schedule is not None:
if ":" in query.old_schedule:
schedule_json['interval'] = 86400
schedule_json['time'] = query.old_schedule
schedule_json["interval"] = 86400
schedule_json["time"] = query.old_schedule
else:
schedule_json['interval'] = query.old_schedule
schedule_json["interval"] = query.old_schedule

conn.execute(
queries
.update()
.where(queries.c.id == query.id)
.values(schedule=MutableDict(schedule_json)))
queries.update()
.where(queries.c.id == query.id)
.values(schedule=MutableDict(schedule_json))
)

op.drop_column("queries", "old_schedule")

op.drop_column('queries', 'old_schedule')

def downgrade():
op.add_column('queries', sa.Column('old_schedule', MutableDict.as_mutable(PseudoJSON), nullable=False, server_default=json.dumps({})))
op.add_column(
"queries",
sa.Column(
"old_schedule",
MutableDict.as_mutable(PseudoJSON),
nullable=False,
server_default=json.dumps({}),
),
)

queries = table(
'queries',
sa.Column('schedule', MutableDict.as_mutable(PseudoJSON)),
sa.Column('old_schedule', MutableDict.as_mutable(PseudoJSON)))
"queries",
sa.Column("schedule", MutableDict.as_mutable(PseudoJSON)),
sa.Column("old_schedule", MutableDict.as_mutable(PseudoJSON)),
)

op.execute(
queries
.update()
.values({'old_schedule': queries.c.schedule}))
op.execute(queries.update().values({"old_schedule": queries.c.schedule}))

op.drop_column('queries', 'schedule')
op.add_column('queries', sa.Column('schedule', sa.String(length=10), nullable=True))
op.drop_column("queries", "schedule")
op.add_column("queries", sa.Column("schedule", sa.String(length=10), nullable=True))

queries = table(
'queries',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('schedule', sa.String(length=10)),
sa.Column('old_schedule', MutableDict.as_mutable(PseudoJSON)))
"queries",
sa.Column("id", sa.Integer, primary_key=True),
sa.Column("schedule", sa.String(length=10)),
sa.Column("old_schedule", MutableDict.as_mutable(PseudoJSON)),
)

conn = op.get_bind()
for query in conn.execute(queries.select()):
scheduleValue = query.old_schedule['interval']
scheduleValue = query.old_schedule["interval"]
if scheduleValue <= 86400:
scheduleValue = query.old_schedule['time']
scheduleValue = query.old_schedule["time"]

conn.execute(
queries
.update()
.where(queries.c.id == query.id)
.values(schedule=scheduleValue))
queries.update()
.where(queries.c.id == query.id)
.values(schedule=scheduleValue)
)

op.drop_column('queries', 'old_schedule')
op.drop_column("queries", "old_schedule")
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,36 @@
# revision identifiers, used by Alembic.
from sqlalchemy.exc import ProgrammingError

revision = '65fc9ede4746'
revision = "65fc9ede4746"
down_revision = None
branch_labels = None
depends_on = None


def upgrade():
try:
op.add_column('queries', sa.Column('is_draft', sa.Boolean, default=True, index=True))
op.add_column('dashboards', sa.Column('is_draft', sa.Boolean, default=True, index=True))
op.add_column(
"queries", sa.Column("is_draft", sa.Boolean, default=True, index=True)
)
op.add_column(
"dashboards", sa.Column("is_draft", sa.Boolean, default=True, index=True)
)
op.execute("UPDATE queries SET is_draft = (name = 'New Query')")
op.execute("UPDATE dashboards SET is_draft = false")
except ProgrammingError as e:
# The columns might exist if you ran the old migrations.
if 'column "is_draft" of relation "queries" already exists' in str(e):
print("Can't run this migration as you already have is_draft columns, please run:")
print("./manage.py db stamp {} # you might need to alter the command to match your environment.".format(revision))
print(
"Can't run this migration as you already have is_draft columns, please run:"
)
print(
"./manage.py db stamp {} # you might need to alter the command to match your environment.".format(
revision
)
)
exit()


def downgrade():
op.drop_column('queries', 'is_draft')
op.drop_column('dashboards', 'is_draft')
op.drop_column("queries", "is_draft")
op.drop_column("dashboards", "is_draft")
Loading

0 comments on commit 2dff8b9

Please sign in to comment.