Skip to content

Commit

Permalink
Refactor and streamline organization and set base for SDK typing (#284)
Browse files Browse the repository at this point in the history
* Refactor and streamline organization tests and resources

Removed deprecated organization methods and updated organization tests. Also, migrated organization.py to Pydantic models, and added mypy typing for more strict type checking. Additionally, enhance auto-paging to work with new models and restructured fixtures for organization tests.

* Switch directories over to new list resources and add typing

* Mark version as alpha

* Formatting and some type fixes

* Add defaults for all optional fields

* Type dsync getters

* Possible path forward for unknown literal values

* Move comments

* Export the untyped type and a type guard. Leave a comment about my thoughts on the approach

* Test out literals of strings vs enums and factor out types and helpers to a typing directory

* Settled on an approach for untyped literals

* A little refactoring

* More accurate validation for UntypedLiteral

* Comments reminding us to clean up

* Add typing to the rest of the dsync methods

* Just some formattin'

* A little more cleanup to unify organizations and dsync

* Fix organizations test

* DirectorySync tests passing, but still need some cleanup

* Do not bump version yet

* Formatting

* Clean up by removing the enum paths

* Small fixed for compat

* More formatting and compat

* Start fixing dsync tests

* Fix another dsync test

* Fix more dsync tests

* Fix params, optional allows None, instead can force default

* Directory sync tests are green

* Fix audit logs test

* Fix organizations test

* Fix auto paging iter tests

* Remove debugging print

* Fix user management tests

* Switch override to typing_extensions

* Build fixes. Proper dict override and remove duplicate model key

* Add directory sync resource to mypy.ini

* Pantera can't spell

* Fix type and delete unused fixtures

* Remove unused import

* Update dsync tests to new pagination helper

* Delete unused fixtures

* Remove some unneeded comments

* PR feedback

* Remove trailing comma in mypy.ini

---------

Co-authored-by: Peter Arzhintar <[email protected]>
  • Loading branch information
jonatascastro12 and tribble authored Jul 22, 2024
1 parent 6fd2bfc commit 6810556
Show file tree
Hide file tree
Showing 24 changed files with 788 additions and 1,439 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,9 @@ jobs:
flake8 . --extend-exclude .devbox --count --select=E9,F7,F82 --show-source --statistics
flake8 . --extend-exclude .devbox --count --exit-zero --max-complexity=10 --statistics
- name: Type Check
run: |
mypy
- name: Test
run: python -m pytest
2 changes: 2 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[mypy]
files=./workos/resources/organizations.py,./workos/resources/directory_sync.py
7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
),
zip_safe=False,
license=about["__license__"],
install_requires=["requests>=2.22.0"],
install_requires=[
"requests>=2.22.0",
"pydantic==2.8.2",
"types-requests==2.32.0.20240712",
],
extras_require={
"dev": [
"flake8",
Expand All @@ -38,6 +42,7 @@
"twine==4.0.2",
"requests==2.30.0",
"urllib3==2.0.2",
"mypy==1.10.1",
],
":python_version<'3.4'": ["enum34"],
},
Expand Down
46 changes: 43 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Dict
import pytest
import requests

from tests.utils.list_resource import list_response_of
import workos


Expand Down Expand Up @@ -45,7 +47,7 @@ def inner(method, response_dict, status_code, headers=None):
def mock(*args, **kwargs):
return MockResponse(response_dict, status_code, headers=headers)

monkeypatch.setattr(requests, method, mock)
monkeypatch.setattr(requests, "request", mock)

return inner

Expand All @@ -56,7 +58,7 @@ def inner(method, content, status_code, headers=None):
def mock(*args, **kwargs):
return MockRawResponse(content, status_code, headers=headers)

monkeypatch.setattr(requests, method, mock)
monkeypatch.setattr(requests, "request", mock)

return inner

Expand All @@ -73,8 +75,46 @@ def capture_and_mock(*args, **kwargs):

return MockResponse(response_dict, status_code, headers=headers)

monkeypatch.setattr(requests, method, capture_and_mock)
monkeypatch.setattr(requests, "request", capture_and_mock)

return (request_args, request_kwargs)

return inner


@pytest.fixture
def mock_pagination_request(monkeypatch):
# Mocking pagination correctly requires us to index into a list of data
# and correctly set the before and after metadata in the response.
def inner(method, data_list, status_code, headers=None):
# For convenient index lookup, store the list of object IDs.
data_ids = list(map(lambda x: x["id"], data_list))

def mock(*args, **kwargs):
params = kwargs.get("params") or {}
request_after = params.get("after", None)
limit = params.get("limit", 10)

if request_after is None:
# First page
start = 0
else:
# A subsequent page, return the first item _after_ the index we locate
start = data_ids.index(request_after) + 1
data = data_list[start : start + limit]
if len(data) < limit or len(data) == 0:
# No more data, set after to None
after = None
else:
# Set after to the last item in this page of results
after = data[-1]["id"]

return MockResponse(
list_response_of(data=data, before=request_after, after=after),
status_code,
headers=headers,
)

monkeypatch.setattr(requests, "request", mock)

return inner
Loading

0 comments on commit 6810556

Please sign in to comment.