Skip to content

Commit f08370c

Browse files
committed
.
1 parent 93ad116 commit f08370c

File tree

6 files changed

+96
-6
lines changed

6 files changed

+96
-6
lines changed

fastapi_users_db_dynamodb/access_token.py

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,29 @@ class DynamoDBBaseAccessTokenTable(Model, Generic[ID]):
2222
__tablename__: str = config.get("DATABASE_TOKENTABLE_NAME")
2323

2424
class Meta:
25+
"""The required `Meta` definitions for PynamoDB.
26+
27+
Args:
28+
table_name (str): The name of the table.
29+
region (str): The AWS region string where the table should be created.
30+
billing_mode (str): The billing mode to use when creating the table. \
31+
Currently only supports `PAY_PER_REQUEST`.
32+
"""
33+
2534
table_name: str = config.get("DATABASE_TOKENTABLE_NAME")
2635
region: str = config.get("DATABASE_REGION")
2736
billing_mode: str = config.get("DATABASE_BILLING_MODE").value
2837

2938
class CreatedAtIndex(GlobalSecondaryIndex):
39+
"""Enable the `created_at` attribute to be a Global Secondary Index.
40+
41+
Args:
42+
GlobalSecondaryIndex (_type_): The Global Secondary Index base class.
43+
"""
44+
3045
class Meta:
46+
"""The metadata for the Global Secondary Index."""
47+
3148
index_name: str = "created_at-index"
3249
projection = AllProjection()
3350

@@ -46,18 +63,29 @@ class Meta:
4663

4764

4865
class DynamoDBBaseAccessTokenTableUUID(DynamoDBBaseAccessTokenTable[UUID_ID]):
66+
"""A base class representing `AccessToken` objects with unique IDs.
67+
68+
Args:
69+
DynamoDBBaseAccessTokenTable (_type_): The underlying table object.
70+
"""
71+
4972
if TYPE_CHECKING: # pragma: no cover
5073
user_id: UUID_ID
5174
else:
5275
user_id: GUID = GUID(null=False)
5376

5477

5578
class DynamoDBAccessTokenDatabase(Generic[AP], AccessTokenDatabase[AP]):
56-
"""Access token database adapter for AWS DynamoDB using aiopynamodb."""
79+
"""Access token database adapter for AWS DynamoDB using `aiopynamodb`."""
5780

5881
access_token_table: type[AP]
5982

6083
def __init__(self, access_token_table: type[AP]):
84+
"""Initialize the Database adapter.
85+
86+
Args:
87+
access_token_table (type[AP]): The table for storing access tokens.
88+
"""
6189
self.access_token_table = access_token_table
6290

6391
async def get_by_token(
@@ -66,7 +94,16 @@ async def get_by_token(
6694
max_age: datetime | None = None,
6795
instant_update: bool = False,
6896
) -> AP | None:
69-
"""Retrieve an access token by token string."""
97+
"""Retrieve an access token by it's token string.
98+
99+
Args:
100+
token (str): The actual token string to be looked for.
101+
max_age (datetime | None, optional): The maximum age of an access token. Expired ones will not be returned. Defaults to None.
102+
instant_update (bool, optional): Whether to use consistent reads. Defaults to False.
103+
104+
Returns:
105+
AP | None: The access token, if found.
106+
"""
70107
await ensure_tables_exist(self.access_token_table) # type: ignore
71108

72109
try:
@@ -83,7 +120,18 @@ async def get_by_token(
83120
return None
84121

85122
async def create(self, create_dict: dict[str, Any] | AP) -> AP:
86-
"""Create a new access token and return an instance of AP."""
123+
"""Create a new access token.
124+
125+
Args:
126+
create_dict (dict[str, Any] | AP): A dictionary holding the data of the access token.
127+
128+
Raises:
129+
ValueError: If the access token could not be created for whatever reason.
130+
ValueError: If the access token could not be created because the table did not exist.
131+
132+
Returns:
133+
AP: The newly created `AccessToken` object.
134+
"""
87135
await ensure_tables_exist(self.access_token_table) # type: ignore
88136

89137
if isinstance(create_dict, dict):
@@ -103,7 +151,19 @@ async def create(self, create_dict: dict[str, Any] | AP) -> AP:
103151
return token
104152

105153
async def update(self, access_token: AP, update_dict: dict[str, Any]) -> AP:
106-
"""Update an existing access token."""
154+
"""Update an existing access token.
155+
156+
Args:
157+
access_token (AP): The `AccessToken` object to be deleted.
158+
update_dict (dict[str, Any]): A dictionary with the changes that should be applied.
159+
160+
Raises:
161+
ValueError: If the access token could not be updated for whatever reason.
162+
ValueError: If the access token could not be updated because the table did not exist.
163+
164+
Returns:
165+
AP: The refreshed `AccessToken` object.
166+
"""
107167
await ensure_tables_exist(self.access_token_table) # type: ignore
108168

109169
try:
@@ -121,7 +181,15 @@ async def update(self, access_token: AP, update_dict: dict[str, Any]) -> AP:
121181
) from e
122182

123183
async def delete(self, access_token: AP) -> None:
124-
"""Delete an access token."""
184+
"""Delete an access token.
185+
186+
Args:
187+
access_token (AP): The `AccessToken` object to be deleted.
188+
189+
Raises:
190+
ValueError: If the access token could not be deleted for whatever reason.
191+
ValueError: If the access token could not be deleted because the table did not exist.
192+
"""
125193
await ensure_tables_exist(self.access_token_table) # type: ignore
126194

127195
try:

fastapi_users_db_dynamodb/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class BillingMode(StrEnum):
1616
Returns:
1717
_type_: The enum member, representing the billing mode.
1818
"""
19+
1920
PAY_PER_REQUEST = "PAY_PER_REQUEST"
2021
# PROVISIONED = "PROVISIONED"
2122

@@ -34,6 +35,7 @@ class __ConfigMap(TypedDict):
3435
Args:
3536
TypedDict (_type_): The base type.
3637
"""
38+
3739
DATABASE_REGION: str
3840
# DATABASE_BILLING_MODE: BillingMode
3941
DATABASE_BILLING_MODE: Literal[BillingMode.PAY_PER_REQUEST]

tests/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,25 @@
99

1010
class User(schemas.BaseUser):
1111
"""A base class representing an `User`."""
12+
1213
first_name: str | None
1314

1415

1516
class UserCreate(schemas.BaseUserCreate):
1617
"""A base class representing the creation of an `User`."""
18+
1719
first_name: str | None
1820

1921

2022
class UserUpdate(schemas.BaseUserUpdate):
2123
"""A base class representing the update of an `User`."""
24+
2225
pass
2326

2427

2528
class UserOAuth(User, schemas.BaseOAuthAccountMixin):
2629
"""A base class representing an `User` with linked `OAuth` accounts."""
30+
2731
pass
2832

2933

tests/test_access_token.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Base(Model):
2424
Args:
2525
Model (_type_): The PynamoDB base class definition.
2626
"""
27+
2728
pass
2829

2930

@@ -34,6 +35,7 @@ class AccessToken(DynamoDBBaseAccessTokenTableUUID, Base):
3435
DynamoDBBaseAccessTokenTableUUID (_type_): The underlying table object.
3536
Base (_type_): The PynamoDB base class definition.
3637
"""
38+
3739
__tablename__: str = config.get("DATABASE_TOKENTABLE_NAME") + "_test"
3840

3941
class Meta:
@@ -45,6 +47,7 @@ class Meta:
4547
billing_mode (str): The billing mode to use when creating the table. \
4648
Currently only supports `PAY_PER_REQUEST`.
4749
"""
50+
4851
table_name: str = config.get("DATABASE_TOKENTABLE_NAME") + "_test"
4952
region: str = config.get("DATABASE_REGION")
5053
billing_mode: str = config.get("DATABASE_BILLING_MODE").value
@@ -57,6 +60,7 @@ class User(DynamoDBBaseUserTableUUID, Base):
5760
DynamoDBBaseUserTableUUID (_type_): The underlying table object.
5861
Base (_type_): The PynamoDB base class definition.
5962
"""
63+
6064
__tablename__: str = config.get("DATABASE_USERTABLE_NAME") + "_test"
6165

6266
class Meta:
@@ -68,6 +72,7 @@ class Meta:
6872
billing_mode (str): The billing mode to use when creating the table. \
6973
Currently only supports `PAY_PER_REQUEST`.
7074
"""
75+
7176
table_name: str = config.get("DATABASE_USERTABLE_NAME") + "_test"
7277
region: str = config.get("DATABASE_REGION")
7378
billing_mode: str = config.get("DATABASE_BILLING_MODE").value
@@ -180,7 +185,7 @@ async def test_insert_existing_token(
180185
dynamodb_access_token_db: DynamoDBAccessTokenDatabase[AccessToken],
181186
user_id: UUID4,
182187
):
183-
"""Test function that creates and saves an already existing `AccessToken`.
188+
"""Test function that creates and saves an already existing `AccessToken`.
184189
185190
Args:
186191
dynamodb_access_token_db (DynamoDBAccessTokenDatabase[AccessToken]): The database instance to use.

tests/test_misc.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@
88

99
class NotAModel:
1010
"""A class representing an invalid `Model`."""
11+
1112
pass
1213

1314

1415
class IncompleteModel(Model):
1516
"""A class representing an incomplete `Model`, which misses required functions."""
17+
1618
pass
1719

1820

1921
class ValidModel(Model):
2022
"""A class representing a valid `Model`."""
23+
2124
class Meta:
2225
"""The required `Meta` definitions for PynamoDB.
2326
@@ -27,6 +30,7 @@ class Meta:
2730
billing_mode (str): The billing mode to use when creating the table. \
2831
Currently only supports `PAY_PER_REQUEST`.
2932
"""
33+
3034
table_name: str = "valid_model_test"
3135
region: str = config.get("DATABASE_REGION")
3236
billing_mode: str = config.get("DATABASE_BILLING_MODE").value

tests/test_users.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class Base(Model):
2222
Args:
2323
Model (_type_): The PynamoDB base class definition.
2424
"""
25+
2526
pass
2627

2728

@@ -32,6 +33,7 @@ class User(DynamoDBBaseUserTableUUID, Base):
3233
DynamoDBBaseUserTableUUID (_type_): The underlying table object.
3334
Base (_type_): The PynamoDB base class definition.
3435
"""
36+
3537
__tablename__: str = config.get("DATABASE_USERTABLE_NAME") + "_test"
3638

3739
class Meta:
@@ -43,6 +45,7 @@ class Meta:
4345
billing_mode (str): The billing mode to use when creating the table. \
4446
Currently only supports `PAY_PER_REQUEST`.
4547
"""
48+
4649
table_name: str = config.get("DATABASE_USERTABLE_NAME") + "_test"
4750
region: str = config.get("DATABASE_REGION")
4851
billing_mode: str = config.get("DATABASE_BILLING_MODE").value
@@ -59,6 +62,7 @@ class OAuthBase(Model):
5962
Args:
6063
Model (_type_): The PynamoDB base class definition.
6164
"""
65+
6266
pass
6367

6468

@@ -69,6 +73,7 @@ class OAuthAccount(DynamoDBBaseOAuthAccountTableUUID, OAuthBase):
6973
DynamoDBBaseOAuthAccountTableUUID (_type_): The underlying table object.
7074
OAuthBase (_type_): The base class for `OAuth`.
7175
"""
76+
7277
pass
7378

7479

@@ -79,6 +84,7 @@ class UserOAuth(DynamoDBBaseUserTableUUID, OAuthBase):
7984
DynamoDBBaseUserTableUUID (_type_): The underlying table object.
8085
OAuthBase (_type_): The base class representing `OAuth` related models.
8186
"""
87+
8288
__tablename__: str = config.get("DATABASE_OAUTHTABLE_NAME") + "_test"
8389

8490
class Meta:
@@ -90,6 +96,7 @@ class Meta:
9096
billing_mode (str): The billing mode to use when creating the table. \
9197
Currently only supports `PAY_PER_REQUEST`.
9298
"""
99+
93100
table_name: str = config.get("DATABASE_OAUTHTABLE_NAME") + "_test"
94101
region: str = config.get("DATABASE_REGION")
95102
billing_mode: str = config.get("DATABASE_BILLING_MODE").value

0 commit comments

Comments
 (0)