Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
82d1d6c
feat: implement dataclasses with methods for parsing
leynier Oct 14, 2021
25e223b
feat: add new types, implement to_dicts and align files with gotrue-js
leynier Oct 15, 2021
1ed9754
feat: add types to API class and align implementation with gotrue-js
leynier Oct 15, 2021
f9ff600
chore: formatting code
leynier Oct 17, 2021
930273f
feat: implement CookieOptions type
leynier Oct 17, 2021
a6dacaf
feat: implement AuthChangeEvent enum
leynier Oct 17, 2021
8c64876
feat: implement Subscription type
leynier Oct 17, 2021
044efe8
feat: implement SupportedStorage abstract storage and MemoryStorage s…
leynier Oct 17, 2021
4ef1b55
feat: add CookieOptions to constructor of GoTrueApi
leynier Oct 17, 2021
0a669de
feat: synchronize implementation of GoTrueClient
leynier Oct 17, 2021
3400431
chore: format conftest.py
leynier Oct 17, 2021
ee916c2
feat: add poetry to CI action and add dependabot config file
leynier Oct 17, 2021
112ce71
chore: fix name of ci test job
leynier Oct 17, 2021
ae0ba3f
chore: change order of strategy parameter
leynier Oct 17, 2021
2ac3930
chore: fix name of ci test job
leynier Oct 17, 2021
da10e87
feat: implement sync/async support with httppx and unasync
leynier Oct 17, 2021
42619ea
feat: add context manager support
leynier Oct 17, 2021
267c62c
chore: add doc to on_auth_state_change
leynier Oct 18, 2021
bfc5fab
chore: format code of sync client
leynier Oct 18, 2021
09f9b47
feat: add pre-commit system for check Pythonic style
leynier Oct 18, 2021
8ddd940
chore: regenerate sync client
leynier Oct 18, 2021
2fbcb70
chore: format code by pre-commit
leynier Oct 18, 2021
6ac5334
feat: add Make rule for infra
leynier Oct 18, 2021
3ab70a5
chore: add dependencies for code coverage and fix tests command
leynier Oct 18, 2021
fcad1af
fix: cycle of references between helpers and types
leynier Oct 18, 2021
5815566
chore: separate tests rule in multiples rules
leynier Oct 18, 2021
9c12bd1
fix: error in remove_item of memory storage
leynier Oct 18, 2021
e7ebc64
fix: remove unnecessary async to on_auth_state_change
leynier Oct 18, 2021
67ecf57
test: implement provider and subscriptions tests
leynier Oct 18, 2021
1ee2946
fix: ci github action
leynier Oct 18, 2021
72b85b5
chore: regenerate sync client
leynier Oct 18, 2021
b3cba71
chore: run ci in all branches
leynier Oct 18, 2021
46373e4
feat: generate tests for sync client
leynier Oct 18, 2021
71a2c8f
test: ignore build_sync.py and conftest.py in Coverage
leynier Oct 18, 2021
0c29382
test: implement tests for api with auto confirm disabled
leynier Oct 18, 2021
b8330c0
test: handle exceptions and use context manager
leynier Oct 18, 2021
08d2558
test: client with sign ups disabled
leynier Oct 18, 2021
4cb8330
feat: force the use of keyword parameters
leynier Oct 18, 2021
c407a63
test: client with auto confirm disabled
leynier Oct 18, 2021
c8daa2a
test: use fixtures of pytest
leynier Oct 18, 2021
9870078
fix: errors in helpers and types
leynier Oct 19, 2021
a653408
fix: error in client update
leynier Oct 19, 2021
b758dba
test: client with auto confirm enabled
leynier Oct 19, 2021
068fe0d
chore: add logs
leynier Oct 19, 2021
e575d9b
test: fix error in provider
leynier Oct 19, 2021
1e65cc3
test: fix expected error message
leynier Oct 19, 2021
96eb94b
test: add various Python versions to CI
leynier Oct 19, 2021
f70fdd2
feat: implement and use cli for unasync
leynier Oct 23, 2021
d1f5fc7
fix: some tipe hints
leynier Oct 23, 2021
843008b
chore: split some make rules
leynier Oct 23, 2021
d224ec1
fix: some fixes and changes requested
leynier Nov 1, 2021
3d226f5
feat: use reflection for parsing dataclasses
leynier Nov 1, 2021
1859aa3
fix: remove email_change_confirm_status from User
leynier Nov 1, 2021
dab27ce
fix: remove Optional to user_metadata of User
leynier Nov 1, 2021
73df8d7
fix: add slack adn spotify to Provider
leynier Nov 1, 2021
d042152
feat: add identities to User
leynier Nov 1, 2021
21d7bda
fix: add Optional to identities of User
leynier Nov 1, 2021
eb86078
test: fix test_sign_up_the_same_user_twice_should_throw_an_error test
leynier Nov 1, 2021
98e27af
fix: change ApiError by APIError
leynier Nov 1, 2021
55c03a6
fix: change ApiError by APIError in docstrings
leynier Nov 1, 2021
b16356d
feat: use annotations from __future__
leynier Nov 1, 2021
13cc086
fix: change Api by API
leynier Nov 3, 2021
0ea666a
test: fix test sign up the same user twice should throw an error
leynier Nov 3, 2021
3333813
feat: use asdict of dataclasses for to_dicts
leynier Nov 4, 2021
3ef3707
feat: add end-of-file-fixer to .pre-commit-config.yaml
leynier Nov 4, 2021
9c7a18c
feat: add --ignore-init-module-imports to .pre-commit-config.yaml
leynier Nov 4, 2021
747f411
fix: .pre-commit-config.yaml format
leynier Nov 4, 2021
f5b0b01
chore: changes by run pre-commit
leynier Nov 4, 2021
08565ac
feat: uuid4().hex instead of str(uuid4())
leynier Nov 4, 2021
b91e556
feat: uuid4().hex instead of str(uuid4()) in _sync client
leynier Nov 4, 2021
c2d37fb
fix: set prefix __ instead of _ for private methods
leynier Nov 4, 2021
e900c49
docs: add comment for email preferences over phone
leynier Nov 4, 2021
b2eb4f2
feat: unify logic of __recover_session and __recover_and_refresh
leynier Nov 4, 2021
45dbc4f
chore: revert to use single _ in "private" methods
leynier Nov 4, 2021
9df4927
deps: add pydantic dependency
leynier Nov 5, 2021
a0e4008
feat: migrate types to pydantic models
leynier Nov 5, 2021
383298a
fix: use parse_obj
leynier Nov 6, 2021
177b619
fix: use directly parse_obj instead of lambdas
leynier Nov 6, 2021
6905d45
fix: use typing annotations
leynier Nov 6, 2021
eaeae46
feat: add pyupgrade pre-commit hook
leynier Nov 6, 2021
cb4624d
Add parse_response method to custom pydantic base model
Nov 14, 2021
0f3210f
Formatting
Nov 14, 2021
4c7003e
fix: use expires_in var for avoid typing warning
leynier Nov 14, 2021
8d2c74e
chore: remove noqa comments
leynier Nov 14, 2021
455794f
feat: add datetime and uuid types
leynier Nov 14, 2021
72f05e2
feat: add create_user and list_users
leynier Nov 15, 2021
d782994
chore: add Python 3.10 to GitHub Action
leynier Nov 15, 2021
2350250
fix: use str for declare Python 3.10
leynier Nov 15, 2021
a261996
chore: remove Python 3.10 for unknow error
leynier Nov 15, 2021
c60718c
feat: allow providing custom api and http client implementation
leynier Nov 15, 2021
57473a2
Add python 3.10 to GH Actions fix
dreinon Nov 15, 2021
64162f6
Use pydantic parse_obj_as helper method
Nov 15, 2021
ce47032
Use latest actions-poetry
Nov 15, 2021
283bd9f
docs: add description to aud field of User model
leynier Nov 15, 2021
ec2c893
feat: add X-Client-Info to default headers
leynier Nov 16, 2021
83e8f5e
chore: update dependencies
leynier Nov 16, 2021
6e501c9
fix: remove duplicate var env in docker-compose.yml
leynier Nov 16, 2021
0e78b62
feat: add devcontainer.json for use github codespaces
leynier Nov 16, 2021
20235fe
docs: update some info of readme
leynier Nov 16, 2021
ec0bdb5
Fix typo in README.md
dreinon Nov 17, 2021
fdc6318
chore: remove unused noqa comment
leynier Nov 17, 2021
427d5d4
Switch isort mirror by isort pre-commit hook
Nov 17, 2021
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
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[run]
omit =
build_sync.py
conftest.py
tests/*
21 changes: 21 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.203.0/containers/python-3/.devcontainer/base.Dockerfile

# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
ARG VARIANT="3.10-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}

# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
ARG NODE_VERSION="none"
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi

# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
# COPY requirements.txt /tmp/pip-tmp/
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
# && rm -rf /tmp/pip-tmp

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
81 changes: 81 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.203.0/containers/python-3
{
"name": "Python 3",
"runArgs": [
"--init"
],
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
// Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local on arm64/Apple Silicon.
"VARIANT": "3.10-bullseye",
// Options
"NODE_VERSION": "lts/*"
}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"python.pythonPath": "/usr/local/bin/python",
"python.languageServer": "Pylance",
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
"python.analysis.diagnosticMode": "workspace",
"files.exclude": {
"**/.ipynb_checkpoints": true,
"**/.pytest_cache": true,
"**/*pycache*": true
},
"python.formatting.provider": "black",
"python.linting.flake8Args": [
"--max-line-length=88",
"--extend-ignore=E203"
],
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
"python.sortImports.args": [
"--multi-line=3",
"--trailing-comma",
"--force-grid-wrap=0",
"--use-parentheses",
"--line-width=88",
]
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-azuretools.vscode-docker",
"donjayamanne.githistory",
"felipecaputo.git-project-manager",
"github.copilot-nightly",
"eamodio.gitlens",
"davidanson.vscode-markdownlint"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
"features": {
"docker-in-docker": "latest",
"git": "latest",
"git-lfs": "latest",
"github-cli": "latest"
}
}
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
target-branch: "main"
43 changes: 14 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,47 +1,32 @@
name: CI

on:
pull_request:
push:
branches:
- main
workflow_dispatch:
on: [pull_request, push, workflow_dispatch]

jobs:
test:
name: Test / OS ${{ matrix.os }} / Node ${{ matrix.node }}
name: Test / OS ${{ matrix.os }} / Python ${{ matrix.python-version }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: [3.7, 3.8, 3.9, '3.10']
runs-on: ${{ matrix.os }}
# TODO(fedden): We need to discuss these steps: We could just use a test-supabase instance or we could update the docker image and use that for the tests.
steps:
- uses: actions/checkout@v2
- name: Clone Repository
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest requests
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Login to Docker Hub
uses: docker/login-action@v1
- name: Set up Poetry
uses: abatilo/actions-poetry@v2.1.4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
poetry-version: 1.1.11
- name: Build Docker image
run: |
cd infra
docker-compose down
docker-compose up -d
run: make run_infra
- name: Sleep for 5 seconds
uses: jakejarvis/wait-action@master
with:
time: "5s"
- name: Test with pytest
run: |
pytest -sx

run: sleep 5
- name: Run Tests
run: make tests
- name: Upload Coverage
uses: codecov/codecov-action@v1
46 changes: 46 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: check-added-large-files
- id: end-of-file-fixer
- id: mixed-line-ending
args: ["--fix=lf"]

- repo: https://github.com/pycqa/isort
rev: 5.10.1
hooks:
- id: isort
args:
[
"--profile",
"black",
"--multi-line=3",
"--trailing-comma",
"--force-grid-wrap=0",
"--use-parentheses",
"--line-width=88",
]

- repo: https://github.com/myint/autoflake.git
rev: v1.4
hooks:
- id: autoflake
args:
[
"--in-place",
"--remove-all-unused-imports",
"--ignore-init-module-imports",
]

- repo: https://github.com/ambv/black
rev: 21.11b0
hooks:
- id: black

- repo: https://github.com/asottile/pyupgrade
rev: v2.29.1
hooks:
- id: pyupgrade
args: ["--py37-plus", "--keep-runtime-typing"]
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
install:
poetry install

install_poetry:
curl -sSL https://install.python-poetry.org | python -
sudo rm -r .venv
poetry install

tests: install tests_only tests_pre_commit

tests_pre_commit:
poetry run pre-commit run --all-files

tests_only:
poetry run pytest --cov=./ --cov-report=xml -vv

run_infra:
cd infra &&\
docker-compose down &&\
docker-compose up -d

run_tests: run_infra tests

build_sync:
poetry run unasync gotrue tests

build_run_tests: build_sync run_tests
echo "Done"
30 changes: 10 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Gotrue-py

This is a Python port of the [supabase js gotrue client](https://github.com/supabase/gotrue-js). The current status is that there is not complete feature pairity when compared with the js-client, but this something we are working on.
This is a Python port of the [supabase js gotrue client](https://github.com/supabase/gotrue-js). The current state is that there is a features parity but with small differences that are mentioned in the section **Differences to the JS client**.

## Installation

We are still working on making the go-true python library more user-friendly. For now here are some sparse notes on how to install the module
We are still working on making the `gotrue` python library more user-friendly. For now here are some sparse notes on how to install the module.

### Poetry

Expand Down Expand Up @@ -34,9 +34,13 @@ const { data, error } = client.sign_up(...)

The other key difference is we do not use pascalCase to encode variable and method names. Instead we use the snake_case convention adopted in the Python language.

## Usage
Also, the `gotrue` library for Python parses the date-time string into `datetime` Python objects. The [JS client](https://github.com/supabase/gotrue-js) keeps the date-time as strings.

To instanciate the client, you'll need the URL and any request headers at a minimum.
## Usage (outdated)

**Important:** This section is outdated, you can be guided by the [JS client documentation](https://supabase.github.io/gotrue-js) because this Python client has a lot of parity with the JS client.

To instantiate the client, you'll need the URL and any request headers at a minimum.

```python
from gotrue import Client
Expand Down Expand Up @@ -77,23 +81,9 @@ assert client.user() is not None
assert client.session() is not None
```

## Tests

At the moment we use a pre-defined supabase instance to test the functionality. This may change over time. You can run the tests like so:

```bash
SUPABASE_TEST_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYxMjYwOTMyMiwiZXhwIjoxOTI4MTg1MzIyfQ.XL9W5I_VRQ4iyQHVQmjG0BkwRfx6eVyYB3uAKcesukg" \
SUPABASE_TEST_URL="https://tfsatoopsijgjhrqplra.supabase.co" \
pytest -sx
```

## Contributions

We would be immensely grateful for any contributions to this project. In particular are the following items:

- [x] Figure out to use either Sessions to manage headers or allow passing in of headers
- [ ] Add documentation.
- [ ] Add more tests.
- [ ] Ensuring feature-parity with the js-client.
- [ ] Supporting 3rd party provider authentication.
- [ ] Implement a js port of setTimeout for the refresh session code.
- Add documentation
- Update `README.md`
38 changes: 25 additions & 13 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Dict, Tuple

import pytest

# store history of failures per test class name and per index in parametrize (if parametrize used)
# store history of failures per test class name and per index
# in parametrize (if parametrize used)
_test_failed_incremental: Dict[str, Dict[Tuple[int, ...], str]] = {}


Expand All @@ -12,14 +14,19 @@ def pytest_runtest_makereport(item, call):
# the test has failed
# retrieve the class name of the test
cls_name = str(item.cls)
# retrieve the index of the test (if parametrize is used in combination with incremental)
parametrize_index = (tuple(item.callspec.indices.values())
if hasattr(item, "callspec") else ())
# retrieve the index of the test (if parametrize is used
# in combination with incremental)
parametrize_index = (
tuple(item.callspec.indices.values())
if hasattr(item, "callspec")
else ()
)
# retrieve the name of the test function
test_name = item.originalname or item.name
# store in _test_failed_incremental the original name of the failed test
_test_failed_incremental.setdefault(cls_name, {}).setdefault(
parametrize_index, test_name)
parametrize_index, test_name
)


def pytest_runtest_setup(item):
Expand All @@ -28,12 +35,17 @@ def pytest_runtest_setup(item):
cls_name = str(item.cls)
# check if a previous test has failed for this class
if cls_name in _test_failed_incremental:
# retrieve the index of the test (if parametrize is used in combination with incremental)
parametrize_index = (tuple(item.callspec.indices.values())
if hasattr(item, "callspec") else ())
# retrieve the name of the first test function to fail for this class name and index
test_name = _test_failed_incremental[cls_name].get(
parametrize_index, None)
# if name found, test has failed for the combination of class name & test name
# retrieve the index of the test (if parametrize is used
# in combination with incremental)
parametrize_index = (
tuple(item.callspec.indices.values())
if hasattr(item, "callspec")
else ()
)
# retrieve the name of the first test function to
# fail for this class name and index
test_name = _test_failed_incremental[cls_name].get(parametrize_index, None)
# if name found, test has failed for the combination of
# class name & test name
if test_name is not None:
pytest.xfail("previous test failed ({})".format(test_name))
pytest.xfail(f"previous test failed ({test_name})")
Binary file removed docs/build/doctrees/environment.pickle
Binary file not shown.
Binary file removed docs/build/doctrees/index.doctree
Binary file not shown.
4 changes: 0 additions & 4 deletions docs/build/html/.buildinfo

This file was deleted.

20 changes: 0 additions & 20 deletions docs/build/html/_sources/index.rst.txt

This file was deleted.

Loading