Skip to content

Commit a38cdec

Browse files
authored
Merge pull request #5 from strawberry-graphql/setup-pre-commit
2 parents b824342 + 8b60e9d commit a38cdec

File tree

12 files changed

+110
-60
lines changed

12 files changed

+110
-60
lines changed

.flake8

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[flake8]
2+
max-line-length = 88
3+
exclude=.venv,.git
4+
ignore = W503,E800
5+
extend-ignore =
6+
# See https://github.com/PyCQA/pycodestyle/issues/373
7+
E203,

.pre-commit-config.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
repos:
2+
- repo: https://github.com/PyCQA/flake8
3+
rev: 3.9.2
4+
hooks:
5+
- id: flake8
6+
additional_dependencies: ["flake8-eradicate==0.4.0"]
7+
8+
- repo: https://github.com/patrick91/pre-commit-alex
9+
rev: aa5da9e54b92ab7284feddeaf52edf14b1690de3
10+
hooks:
11+
- id: alex
12+
exclude: CHANGELOG.md
13+
14+
- repo: https://github.com/pre-commit/mirrors-prettier
15+
rev: v2.3.2
16+
hooks:
17+
- id: prettier
18+
files: '.*\.mdx?$'
19+
20+
- repo: https://github.com/pre-commit/pre-commit-hooks
21+
rev: v4.0.1
22+
hooks:
23+
- id: trailing-whitespace
24+
- id: check-merge-conflict
25+
- id: end-of-file-fixer
26+
- id: check-toml
27+
28+
- repo: https://github.com/humitos/mirrors-autoflake.git
29+
rev: v1.1
30+
hooks:
31+
- id: autoflake
32+
args: ['--in-place', '--remove-all-unused-imports', '--remove-unused-variable']
33+
34+
- repo: https://github.com/psf/black
35+
rev: 21.8b0
36+
hooks:
37+
- id: black

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# examples
2+
23
Example on how to use Strawberry

django-subscriptions-rxdb/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# django-subscriptions-rxdb
22

33
## tl;dr
4+
45
This example reproduces the server-side component of the RxDB GraphQL example, with a couple of extras, which can be found [here](https://github.com/pubkey/rxdb/tree/master/examples/graphql). Checkout RxDB and run the GraphQL example. When running Ok, change `export const GRAPHQL_PORT = 10102;` and `export const GRAPHQL_SUBSCRIPTION_PORT = 10103;` ([lines 1 and 3 of this file](https://github.com/pubkey/rxdb/blob/master/examples/graphql/shared.js)) to equal `8000`. Then in the directory of this README file, `make install && make run`. More information about RxDB and GraphQL synchronisation can be found [here](https://rxdb.info/replication-graphql.html).
56

67
## Requirements
8+
79
- [Clone of RxDB](https://github.com/pubkey/rxdb)
810
- [Python 3.8+](https://www.python.org/downloads/) (might work with other versions, not tested)
911
- [Poetry](https://python-poetry.org/)
@@ -13,11 +15,12 @@ This example reproduces the server-side component of the RxDB GraphQL example, w
1315
Tested on Ubuntu 20.04, should work everywhere these are available with no changes.
1416

1517
## Reason for this example
16-
While connectivity is getting better around the world every year, every user will always at least have moments when their connection is spotty, if not completely absent (at human prices) for certain periods (eg., on a plane). With an offline-first, local database and other offline-first tech (service workers, etc.), it is possible to develop web-technology-based applications that will continue to offer much of their functionality offline, with realtime sync when they are online. This really is the best of both worlds, and can give much more fluid and friendly usage when connections are spotty.
18+
19+
While connectivity is getting better around the world every year, every user will always have moments when their connection is spotty (eg. on a plane). With an offline-first, local database and other offline-first tech (service workers, etc.), it is possible to develop web-technology-based applications that will continue to offer much of their functionality offline, with realtime sync when they are online. This really is the best of both worlds, and can give much more fluid and friendly usage when connections are spotty.
1720

1821
So you already have a Django-based app, and want to add some rich, client-side, offline-first functionality without starting from scratch? This is an example of some of the server-side code for one way of starting out.
1922

20-
The RxDB component of this is not included here to keep things as light as possible. Offline-first has complexities that need to be mastered, so this is not intended to be a template or even a particularly good way of doing things, just a rough example to get you started with `rxdb`, `strawberry`, `django` and `broadcaster`.
23+
The RxDB component of this is not included here to keep things as light as possible. Offline-first has complexities that need to be mastered, so this is not intended to be a template or even a particularly good way of doing things. It's one rough example to get you started with `rxdb`, `strawberry`, `django` and `broadcaster`.
2124

2225
### The full example stack
2326

@@ -29,6 +32,6 @@ If you use PostgreSQL then you will have to set up a database like you would for
2932
make install-postgres
3033
```
3134

32-
Now simply run `make run` as usual to run it.
35+
Now run `make run` as usual to run it.
3336

34-
This extended setup shows how you can have multiple instances of your Django (in a Kubernetes cluster, for example), and realtime notifications will work for any client connected to any of the servers. This example uses [broadcaster](https://github.com/encode/broadcaster) for subscription notifications which, in addition to `postgres`, supports `memory` (for a single node), `redis` and `kafka`. If your `django` is not using `postgres` and/or you are using one of the other options for caching or messaging, you might want to use one of those. It should Just Work if you follow the `broadcaster` docs for the connection string.
37+
This extended setup shows how you can have multiple instances of your Django (in a Kubernetes cluster, for example), and realtime notifications will work for any client connected to any of the servers. This example uses [broadcaster](https://github.com/encode/broadcaster) for subscription notifications which, in addition to `postgres`, supports `memory` (for a single node), `redis` and `kafka`. If your `django` is not using `postgres` and/or you are using one of the other options for caching or messaging, you might want to use one of those. It should work if you follow the `broadcaster` docs for the connection string.

django-subscriptions-rxdb/manage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
def main():
88
"""Run administrative tasks."""
9-
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo.settings')
9+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo.settings")
1010
try:
1111
from django.core.management import execute_from_command_line
1212
except ImportError as exc:
@@ -18,5 +18,5 @@ def main():
1818
execute_from_command_line(sys.argv)
1919

2020

21-
if __name__ == '__main__':
21+
if __name__ == "__main__":
2222
main()

django-subscriptions-rxdb/src/api/context.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ async def get_broadcast():
1919
if dbinfo.get("PORT")
2020
else dbinfo.get("HOST")
2121
)
22-
dsnstr = f"postgresql://{dbinfo.get('USER')}:{dbinfo.get('PASSWORD')}@{host}/{dbinfo.get('NAME')}"
22+
dsnstr = (
23+
f"postgresql://{dbinfo.get('USER')}:"
24+
f"{dbinfo.get('PASSWORD')}@{host}/{dbinfo.get('NAME')}"
25+
)
2326
broadcast = Broadcast(dsnstr)
2427
else:
2528
broadcast = Broadcast("memory://")

django-subscriptions-rxdb/src/api/models.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3-
from asgiref.sync import sync_to_async
4-
from django.contrib.auth.models import User
53
from django.db import models
6-
from django.db.models import Q
74

85

96
class Hero(models.Model):

django-subscriptions-rxdb/src/api/schema.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
# -*- coding: utf-8 -*-
22

3-
import asyncio
43
import time
5-
import traceback
64
from typing import List, Optional
75

86
import strawberry
97
from asgiref.sync import sync_to_async
108
from django.core.serializers import deserialize, serialize
119
from django.db.models import Q
12-
from strawberry_django import ModelResolver, types
10+
from strawberry_django import ModelResolver
1311

1412
from api import models
1513

@@ -36,9 +34,9 @@ class Hero(HeroResolver.output_type):
3634
# updatedAt: Float
3735
# deleted: Boolean!
3836
# }
39-
# The client code expects the input type to be called "HeroInput", not "CreateHero", which is the default
40-
# We therefore need to create a new type via the strawberry.input decorator
41-
# class HeroInput(HeroResolver.create_input_type):
37+
# The client code expects the input type to be called "HeroInput",
38+
# not "CreateHero", which is the default We therefore need to create a new type
39+
# via the strawberry.input decorator
4240
@strawberry.input
4341
class HeroInput(HeroResolver.create_input_type):
4442
pass
@@ -67,11 +65,11 @@ def filterHeroes(
6765

6866
@strawberry.type
6967
class Query:
70-
## to include the auto-generated methods from strawberry-graphql-django:
71-
## - hero(id: ID!): Hero!
72-
## - heros(filters: [String!] = null): [Hero!]!
73-
## declare the class as
74-
## class Query(HeroResolver.query()):
68+
# to include the auto-generated methods from strawberry-graphql-django:
69+
# - hero(id: ID!): Hero!
70+
# - heros(filters: [String!] = null): [Hero!]!
71+
# declare the class as
72+
# class Query(HeroResolver.query()):
7573

7674
# type Query {
7775
# feedHero(id: String, updatedAt: Float, limit: Int!): [Hero!]!

django-subscriptions-rxdb/src/demo/settings.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@
6666

6767
AUTH_PASSWORD_VALIDATORS = [
6868
{
69-
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
69+
"NAME": (
70+
"django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
71+
),
7072
},
7173
{
7274
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",

django-subscriptions/demo/settings.py

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
2121

2222
# SECURITY WARNING: keep the secret key used in production secret!
23-
SECRET_KEY = 'p-h@br&tcqetcsaa%))9%5-80qjv&*-2_@6eddvp!3m)z#kyq%'
23+
SECRET_KEY = "p-h@br&tcqetcsaa%))9%5-80qjv&*-2_@6eddvp!3m)z#kyq%"
2424

2525
# SECURITY WARNING: don't run with debug turned on in production!
2626
DEBUG = True
@@ -31,52 +31,52 @@
3131
# Application definition
3232

3333
INSTALLED_APPS = [
34-
'django.contrib.admin',
35-
'django.contrib.auth',
36-
'django.contrib.contenttypes',
37-
'django.contrib.sessions',
38-
'django.contrib.messages',
39-
'django.contrib.staticfiles',
34+
"django.contrib.admin",
35+
"django.contrib.auth",
36+
"django.contrib.contenttypes",
37+
"django.contrib.sessions",
38+
"django.contrib.messages",
39+
"django.contrib.staticfiles",
4040
]
4141

4242
MIDDLEWARE = [
43-
'django.middleware.security.SecurityMiddleware',
44-
'django.contrib.sessions.middleware.SessionMiddleware',
45-
'django.middleware.common.CommonMiddleware',
46-
'django.middleware.csrf.CsrfViewMiddleware',
47-
'django.contrib.auth.middleware.AuthenticationMiddleware',
48-
'django.contrib.messages.middleware.MessageMiddleware',
49-
'django.middleware.clickjacking.XFrameOptionsMiddleware',
43+
"django.middleware.security.SecurityMiddleware",
44+
"django.contrib.sessions.middleware.SessionMiddleware",
45+
"django.middleware.common.CommonMiddleware",
46+
"django.middleware.csrf.CsrfViewMiddleware",
47+
"django.contrib.auth.middleware.AuthenticationMiddleware",
48+
"django.contrib.messages.middleware.MessageMiddleware",
49+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
5050
]
5151

52-
ROOT_URLCONF = 'demo.urls'
52+
ROOT_URLCONF = "demo.urls"
5353

5454
TEMPLATES = [
5555
{
56-
'BACKEND': 'django.template.backends.django.DjangoTemplates',
57-
'DIRS': [],
58-
'APP_DIRS': True,
59-
'OPTIONS': {
60-
'context_processors': [
61-
'django.template.context_processors.debug',
62-
'django.template.context_processors.request',
63-
'django.contrib.auth.context_processors.auth',
64-
'django.contrib.messages.context_processors.messages',
56+
"BACKEND": "django.template.backends.django.DjangoTemplates",
57+
"DIRS": [],
58+
"APP_DIRS": True,
59+
"OPTIONS": {
60+
"context_processors": [
61+
"django.template.context_processors.debug",
62+
"django.template.context_processors.request",
63+
"django.contrib.auth.context_processors.auth",
64+
"django.contrib.messages.context_processors.messages",
6565
],
6666
},
6767
},
6868
]
6969

70-
WSGI_APPLICATION = 'demo.wsgi.application'
70+
WSGI_APPLICATION = "demo.wsgi.application"
7171

7272

7373
# Database
7474
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
7575

7676
DATABASES = {
77-
'default': {
78-
'ENGINE': 'django.db.backends.sqlite3',
79-
'NAME': BASE_DIR / 'db.sqlite3',
77+
"default": {
78+
"ENGINE": "django.db.backends.sqlite3",
79+
"NAME": BASE_DIR / "db.sqlite3",
8080
}
8181
}
8282

@@ -86,26 +86,28 @@
8686

8787
AUTH_PASSWORD_VALIDATORS = [
8888
{
89-
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
89+
"NAME": (
90+
"django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
91+
),
9092
},
9193
{
92-
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
94+
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
9395
},
9496
{
95-
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
97+
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
9698
},
9799
{
98-
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
100+
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
99101
},
100102
]
101103

102104

103105
# Internationalization
104106
# https://docs.djangoproject.com/en/3.1/topics/i18n/
105107

106-
LANGUAGE_CODE = 'en-us'
108+
LANGUAGE_CODE = "en-us"
107109

108-
TIME_ZONE = 'UTC'
110+
TIME_ZONE = "UTC"
109111

110112
USE_I18N = True
111113

@@ -117,4 +119,4 @@
117119
# Static files (CSS, JavaScript, Images)
118120
# https://docs.djangoproject.com/en/3.1/howto/static-files/
119121

120-
STATIC_URL = '/static/'
122+
STATIC_URL = "/static/"

0 commit comments

Comments
 (0)