Skip to content

Commit 112d178

Browse files
committed
feat: add readme updates for write conflict changes
1 parent 2a75532 commit 112d178

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,132 @@ body = ClientWriteRequest(
747747

748748
response = await fga_client.write(body, options)
749749
```
750+
###### Conflict Options
751+
752+
OpenFGA v1.10.0 introduced support for write conflict options to handle duplicate writes and missing deletes gracefully. These options help avoid unnecessary error handling logic in client code.
753+
754+
**Available Options:**
755+
756+
- `on_duplicate` - Controls behavior when writing a tuple that already exists:
757+
- `ERROR` (default): Returns an error if an identical tuple already exists
758+
- `IGNORE`: Silently ignores duplicate writes (treats as no-op)
759+
760+
- `on_missing` - Controls behavior when deleting a tuple that doesn't exist:
761+
- `ERROR` (default): Returns an error if the tuple doesn't exist
762+
- `IGNORE`: Silently ignores deletes of non-existent tuples (treats as no-op)
763+
764+
**Example: Ignoring duplicate writes**
765+
766+
```python
767+
# from openfga_sdk import OpenFgaClient
768+
# from openfga_sdk.client.models import ClientTuple, ClientWriteRequest
769+
# from openfga_sdk.client.models.write_conflict_opts import (
770+
# ClientWriteRequestOnDuplicateWrites,
771+
# ConflictOptions,
772+
# )
773+
774+
# Initialize the fga_client
775+
# fga_client = OpenFgaClient(configuration)
776+
777+
options = {
778+
"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1",
779+
"conflict": ConflictOptions(
780+
on_duplicate_writes=ClientWriteRequestOnDuplicateWrites.IGNORE
781+
)
782+
}
783+
784+
body = ClientWriteRequest(
785+
writes=[
786+
ClientTuple(
787+
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
788+
relation="viewer",
789+
object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
790+
),
791+
],
792+
)
793+
794+
# This will succeed even if the tuple already exists
795+
response = await fga_client.write(body, options)
796+
```
797+
798+
**Example: Ignoring missing deletes**
799+
800+
```python
801+
# from openfga_sdk import OpenFgaClient
802+
# from openfga_sdk.client.models import ClientTuple, ClientWriteRequest
803+
# from openfga_sdk.client.models.write_conflict_opts import (
804+
# ClientWriteRequestOnMissingDeletes,
805+
# ConflictOptions,
806+
# )
807+
808+
# Initialize the fga_client
809+
# fga_client = OpenFgaClient(configuration)
810+
811+
options = {
812+
"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1",
813+
"conflict": ConflictOptions(
814+
on_missing_deletes=ClientWriteRequestOnMissingDeletes.IGNORE
815+
)
816+
}
817+
818+
body = ClientWriteRequest(
819+
deletes=[
820+
ClientTuple(
821+
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
822+
relation="writer",
823+
object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
824+
),
825+
],
826+
)
827+
828+
# This will succeed even if the tuple doesn't exist
829+
response = await fga_client.write(body, options)
830+
```
831+
832+
**Example: Using both conflict options together**
833+
834+
```python
835+
# from openfga_sdk import OpenFgaClient
836+
# from openfga_sdk.client.models import ClientTuple, ClientWriteRequest
837+
# from openfga_sdk.client.models.write_conflict_opts import (
838+
# ClientWriteRequestOnDuplicateWrites,
839+
# ClientWriteRequestOnMissingDeletes,
840+
# ConflictOptions,
841+
# )
842+
843+
# Initialize the fga_client
844+
# fga_client = OpenFgaClient(configuration)
845+
846+
options = {
847+
"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1",
848+
"conflict": ConflictOptions(
849+
on_duplicate_writes=ClientWriteRequestOnDuplicateWrites.IGNORE,
850+
on_missing_deletes=ClientWriteRequestOnMissingDeletes.IGNORE,
851+
)
852+
}
853+
854+
body = ClientWriteRequest(
855+
writes=[
856+
ClientTuple(
857+
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
858+
relation="viewer",
859+
object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
860+
),
861+
],
862+
deletes=[
863+
ClientTuple(
864+
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
865+
relation="writer",
866+
object="document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a",
867+
),
868+
],
869+
)
870+
871+
# Both operations will succeed regardless of tuple existence
872+
response = await fga_client.write(body, options)
873+
```
874+
875+
For a complete working example, see the [conflict-options example](https://github.com/openfga/python-sdk/tree/main/example/conflict-options).
750876

751877
#### Relationship Queries
752878

0 commit comments

Comments
 (0)