Skip to content

Commit 67f328e

Browse files
authored
Port Python SDK changes (#437)
2 parents 5374fc6 + e09a27b commit 67f328e

34 files changed

+2040
-669
lines changed

config/clients/python/CHANGELOG.md.mustache

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## v0.7.2
4+
5+
### [0.7.2](https://github.com/openfga/python-sdk/compare/v0.7.1...v0.7.2) (2024-09-22)
6+
7+
This release includes improvements to the OpenTelemetry configuration API introduced in the previous releases
8+
9+
- refactor: improve OpenTelemetry configuration (#127)
10+
11+
This release also includes fixes for several bugs identified in previous releases:
12+
13+
- fix: ensure max_parallel_requests is an int value in batch_check (#132)
14+
- fix: inconsistency in 429 handling between sync/async client (#131)
15+
- fix: ensure telemetry is reported when API exceptions are raised (#127)
16+
317
## v0.7.1
418

519
### [0.7.1](https://github.com/openfga/python-sdk/compare/v0.7.0...v0.7.1) (2024-09-16)

config/clients/python/config.overrides.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"sdkId": "python",
33
"gitRepoId": "python-sdk",
44
"packageName": "openfga_sdk",
5-
"packageVersion": "0.7.1",
5+
"packageVersion": "0.7.2",
66
"packageDescription": "Python SDK for OpenFGA",
77
"packageDetailedDescription": "This is an autogenerated python SDK for OpenFGA. It provides a wrapper around the [OpenFGA API definition](https://openfga.dev/api).",
88
"fossaComplianceNoticeId": "2f8a8629-b46c-435e-b8cd-1174a674fb4b",
@@ -188,6 +188,10 @@
188188
"destinationFilename": "openfga_sdk/telemetry/telemetry.py",
189189
"templateType": "SupportingFiles"
190190
},
191+
"src/telemetry/utilities.py.mustache": {
192+
"destinationFilename": "openfga_sdk/telemetry/utilities.py",
193+
"templateType": "SupportingFiles"
194+
},
191195
"src/__init__.py.mustache": {
192196
"destinationFilename": "openfga_sdk/__init__.py",
193197
"templateType": "SupportingFiles"
@@ -281,6 +285,10 @@
281285
"destinationFilename": "test/telemetry/telemetry_test.py",
282286
"templateType": "SupportingFiles"
283287
},
288+
"test/telemetry/utilities_test.py.mustache": {
289+
"destinationFilename": "test/telemetry/utilities_test.py",
290+
"templateType": "SupportingFiles"
291+
},
284292
"test/__init__.py.mustache": {
285293
"destinationFilename": "test/__init__.py",
286294
"templateType": "SupportingFiles"

config/clients/python/template/.github/workflows/main.yaml.mustache

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222

2323
steps:
2424
- name: Checkout code
25-
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
25+
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
2626
with:
2727
fetch-depth: 0
2828

@@ -60,7 +60,7 @@ jobs:
6060

6161
- if: matrix.python-version == '3.10'
6262
name: Upload coverage to Codecov
63-
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
63+
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
6464
continue-on-error: true
6565
with:
6666
token: ${{ secrets.CODECOV_TOKEN }}
@@ -75,7 +75,7 @@ jobs:
7575
id-token: write # Required for PyPI trusted publishing
7676

7777
steps:
78-
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
78+
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
7979
with:
8080
fetch-depth: 0
8181

@@ -98,15 +98,15 @@ jobs:
9898
python setup.py sdist bdist_wheel
9999

100100
- name: Publish package
101-
uses: pypa/gh-action-pypi-publish@8a08d616893759ef8e1aa1f2785787c0b97e20d6 # v1.10.0
101+
uses: pypa/gh-action-pypi-publish@f7600683efdcb7656dec5b29656edb7bc586e597 # v1.10.3
102102

103103
create-release:
104104
runs-on: ubuntu-latest
105105
if: startsWith(github.ref, 'refs/tags/v')
106106
needs: [publish]
107107

108108
steps:
109-
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
109+
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
110110
with:
111111
fetch-depth: 0
112112

config/clients/python/template/docs/opentelemetry.md.mustache

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ If you configure the OpenTelemetry SDK, these metrics will be exported and sent
2626
| `fga-client.request.duration` | Histogram | Yes | Total request time for FGA requests, in milliseconds |
2727
| `fga-client.query.duration` | Histogram | Yes | Time taken by the FGA server to process and evaluate the request, in milliseconds |
2828
| `fga-client.credentials.request` | Counter | Yes | Total number of new token requests initiated using the Client Credentials flow |
29+
| `fga-client.request` | Counter | No | Total number of requests made to the FGA server |
2930

3031
### Supported Attributes
3132

@@ -42,7 +43,7 @@ If you configure the OpenTelemetry SDK, these metrics will be exported and sent
4243
| `http.request.method` | string | Yes | HTTP method for the request |
4344
| `http.request.resend_count` | int | Yes | Number of retries attempted, if any |
4445
| `http.response.status_code` | int | Yes | Status code of the response (e.g., `200` for success) |
45-
| `http.server.request.duration` | int | Yes | Time taken by the FGA server to process and evaluate the request, in milliseconds |
46+
| `http.server.request.duration` | int | No | Time taken by the FGA server to process and evaluate the request, in milliseconds |
4647
| `url.scheme` | string | Yes | HTTP scheme of the request (`http`/`https`) |
4748
| `url.full` | string | Yes | Full URL of the request |
4849
| `user_agent.original` | string | Yes | User Agent used in the query |
@@ -102,15 +103,15 @@ configuration = ClientConfiguration(
102103
store_id=os.getenv("FGA_STORE_ID"),
103104
authorization_model_id=os.getenv("FGA_AUTHORIZATION_MODEL_ID"),
104105

105-
# If you are comfortable with the default configuration outlined in the tables above, you can omit providing your own TelemetryConfiguration object.
106-
telemetry=TelemetryConfiguration(
107-
metrics=TelemetryMetricsConfiguration(
108-
histogram_request_duration=TelemetryMetricConfiguration(
109-
attr_fga_client_request_method=True,
110-
attr_http_response_status_code=True,
111-
),
112-
),
113-
),
106+
# If you are comfortable with the default configuration outlined in the tables above, you can omit providing your own TelemetryConfiguration object, as one will be created for you.
107+
telemetry={
108+
"metrics": {
109+
"fga-client.request.duration": {
110+
"fga-client.request.method": True,
111+
"http.response.status_code": True,
112+
},
113+
},
114+
},
114115
)
115116

116117
fga = OpenFgaClient(configuration)

config/clients/python/template/example/opentelemetry/main.py.mustache

Lines changed: 57 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@ from opentelemetry.sdk.metrics.export import (
1515
)
1616
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
1717

18-
from {{packageName}}.telemetry.configuration import (
19-
TelemetryConfiguration,
20-
TelemetryMetricConfiguration,
21-
TelemetryMetricsConfiguration,
22-
)
23-
2418
# For usage convenience of this example, we will import the OpenFGA SDK from the parent directory.
2519
sdk_path = os.path.realpath(os.path.join(os.path.abspath(__file__), "..", "..", ".."))
2620
sys.path.insert(0, sdk_path)
@@ -36,7 +30,7 @@ from {{packageName}}.credentials import (
3630
Credentials,
3731
)
3832
from {{packageName}}.exceptions import FgaValidationException
39-
33+
from {{packageName}}.telemetry.configuration import TelemetryConfiguration
4034

4135
class app:
4236
"""
@@ -88,62 +82,62 @@ class app:
8882

8983
if not self._telemetry:
9084
# Configure the telemetry metrics to be collected.
91-
# Note: the following represents the default configuration values, so unless you want to change them, you can omit this step.
92-
self._telemetry = TelemetryConfiguration(
93-
metrics=TelemetryMetricsConfiguration(
94-
counter_credentials_request=TelemetryMetricConfiguration(
95-
attr_fga_client_request_client_id=True,
96-
attr_fga_client_request_method=True,
97-
attr_fga_client_request_model_id=True,
98-
attr_fga_client_request_store_id=True,
99-
attr_fga_client_response_model_id=True,
100-
attr_fga_client_user=False,
101-
attr_http_client_request_duration=False,
102-
attr_http_host=True,
103-
attr_http_request_method=True,
104-
attr_http_request_resend_count=True,
105-
attr_http_response_status_code=True,
106-
attr_http_server_request_duration=False,
107-
attr_http_url_scheme=True,
108-
attr_http_url_full=True,
109-
attr_user_agent_original=True,
110-
),
111-
histogram_request_duration=TelemetryMetricConfiguration(
112-
attr_fga_client_request_client_id=True,
113-
attr_fga_client_request_method=True,
114-
attr_fga_client_request_model_id=True,
115-
attr_fga_client_request_store_id=True,
116-
attr_fga_client_response_model_id=True,
117-
attr_fga_client_user=False,
118-
attr_http_client_request_duration=False,
119-
attr_http_host=True,
120-
attr_http_request_method=True,
121-
attr_http_request_resend_count=True,
122-
attr_http_response_status_code=True,
123-
attr_http_server_request_duration=False,
124-
attr_http_url_scheme=True,
125-
attr_http_url_full=True,
126-
attr_user_agent_original=True,
127-
),
128-
histogram_query_duration=TelemetryMetricConfiguration(
129-
attr_fga_client_request_client_id=True,
130-
attr_fga_client_request_method=True,
131-
attr_fga_client_request_model_id=True,
132-
attr_fga_client_request_store_id=True,
133-
attr_fga_client_response_model_id=True,
134-
attr_fga_client_user=False,
135-
attr_http_client_request_duration=False,
136-
attr_http_host=True,
137-
attr_http_request_method=True,
138-
attr_http_request_resend_count=True,
139-
attr_http_response_status_code=True,
140-
attr_http_server_request_duration=False,
141-
attr_http_url_scheme=True,
142-
attr_http_url_full=True,
143-
attr_user_agent_original=True,
144-
),
145-
),
146-
)
85+
# Note: the following represents the default configuration values, so unless you want to customize what's reported, you can omit this.
86+
self._telemetry = {
87+
"metrics": {
88+
"fga-client.credentials.request": {
89+
"fga-client.request.client_id": True,
90+
"fga-client.request.method": True,
91+
"fga-client.request.model_id": True,
92+
"fga-client.request.store_id": True,
93+
"fga-client.response.model_id": True,
94+
"fga-client.user": False,
95+
"http.client.request.duration": False,
96+
"http.host": True,
97+
"http.request.method": True,
98+
"http.request.resend_count": True,
99+
"http.response.status_code": True,
100+
"http.server.request.duration": False,
101+
"url.scheme": True,
102+
"url.full": True,
103+
"user_agent.original": True,
104+
},
105+
"fga-client.request.duration": {
106+
"fga-client.request.client_id": True,
107+
"fga-client.request.method": True,
108+
"fga-client.request.model_id": True,
109+
"fga-client.request.store_id": True,
110+
"fga-client.response.model_id": True,
111+
"fga-client.user": False,
112+
"http.client.request.duration": False,
113+
"http.host": True,
114+
"http.request.method": True,
115+
"http.request.resend_count": True,
116+
"http.response.status_code": True,
117+
"http.server.request.duration": False,
118+
"url.scheme": True,
119+
"url.full": True,
120+
"user_agent.original": True,
121+
},
122+
"fga-client.query.duration": {
123+
"fga-client.request.client_id": True,
124+
"fga-client.request.method": True,
125+
"fga-client.request.model_id": True,
126+
"fga-client.request.store_id": True,
127+
"fga-client.response.model_id": True,
128+
"fga-client.user": False,
129+
"http.client.request.duration": False,
130+
"http.host": True,
131+
"http.request.method": True,
132+
"http.request.resend_count": True,
133+
"http.response.status_code": True,
134+
"http.server.request.duration": False,
135+
"url.scheme": True,
136+
"url.full": True,
137+
"user_agent.original": True,
138+
},
139+
}
140+
}
147141

148142
self._configuration.telemetry = self._telemetry
149143

config/clients/python/template/src/__init__.py.mustache

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ from {{packageName}}.exceptions import ApiException
2020
{{/model}}{{/models}}
2121
from {{packageName}}.telemetry.configuration import (
2222
TelemetryConfiguration,
23+
TelemetryConfigurations,
24+
TelemetryConfigurationType,
2325
TelemetryMetricConfiguration,
2426
TelemetryMetricsConfiguration,
2527
)

config/clients/python/template/src/api.py.mustache

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ class {{classname}}:
2525
if api_client.configuration is not None:
2626
credentials = api_client.configuration.credentials
2727
if credentials is not None and credentials.method == "client_credentials":
28-
self._oauth2_client = OAuth2Client(credentials)
28+
self._oauth2_client = OAuth2Client(
29+
credentials, api_client.configuration
30+
)
2931

3032
self._telemetry = Telemetry()
3133

@@ -329,38 +331,14 @@ class {{classname}}:
329331
response_types_map = {}
330332
{{/returnType}}
331333

332-
telemetry_attributes: dict[TelemetryAttribute, str] = {
333-
TelemetryAttributes.fga_client_request_method: "{{operationId}}"
334+
telemetry_attributes: dict[TelemetryAttribute, str | int] = {
335+
TelemetryAttributes.fga_client_request_method: "{{operationId}}",
336+
TelemetryAttributes.fga_client_request_store_id: self.api_client.get_store_id(),
337+
TelemetryAttributes.fga_client_request_model_id: local_var_params.get(
338+
"authorization_model_id", ""
339+
),
334340
}
335341

336-
try:
337-
if store_id:
338-
telemetry_attributes[
339-
TelemetryAttributes.fga_client_request_store_id
340-
] = store_id
341-
except:
342-
pass
343-
344-
try:
345-
if body_params.tuple_key:
346-
telemetry_attributes[TelemetryAttributes.fga_client_user] = (
347-
body_params.tuple_key.user
348-
)
349-
except:
350-
pass
351-
352-
try:
353-
if "authorization_model_id" in local_var_params:
354-
telemetry_attributes[
355-
TelemetryAttributes.fga_client_request_model_id
356-
] = local_var_params["authorization_model_id"]
357-
elif body_params.authorization_model_id:
358-
telemetry_attributes[
359-
TelemetryAttributes.fga_client_request_model_id
360-
] = body_params.authorization_model_id
361-
except:
362-
pass
363-
364342
return {{#asyncio}}await ({{/asyncio}}self.api_client.call_api(
365343
'{{{path}}}'.replace('{store_id}', store_id), '{{httpMethod}}',
366344
path_params,

0 commit comments

Comments
 (0)