payi 0.1.0a50__py3-none-any.whl → 0.1.0a52__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of payi might be problematic. Click here for more details.
- payi/_version.py +1 -1
- payi/lib/helpers.py +6 -6
- payi/lib/instrument.py +43 -18
- payi/resources/ingest.py +33 -28
- payi/types/ingest_event_param.py +0 -2
- payi/types/ingest_units_params.py +2 -0
- {payi-0.1.0a50.dist-info → payi-0.1.0a52.dist-info}/METADATA +1 -1
- {payi-0.1.0a50.dist-info → payi-0.1.0a52.dist-info}/RECORD +10 -10
- {payi-0.1.0a50.dist-info → payi-0.1.0a52.dist-info}/WHEEL +0 -0
- {payi-0.1.0a50.dist-info → payi-0.1.0a52.dist-info}/licenses/LICENSE +0 -0
payi/_version.py
CHANGED
payi/lib/helpers.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
1
|
from typing import Dict, List, Union
|
|
3
2
|
|
|
4
3
|
PAYI_BASE_URL = "https://api.pay-i.com"
|
|
@@ -11,12 +10,13 @@ class PayiHeaderNames:
|
|
|
11
10
|
user_id:str = "xProxy-User-ID"
|
|
12
11
|
route_as_resource:str = "xProxy-RouteAs-Resource"
|
|
13
12
|
provider_base_uri = "xProxy-Provider-BaseUri"
|
|
13
|
+
resource_scope:str = "xProxy-Resource-Scope"
|
|
14
14
|
|
|
15
|
-
class PayiCategories
|
|
16
|
-
anthropic
|
|
17
|
-
openai = "system.openai"
|
|
18
|
-
azure_openai = "system.azureopenai"
|
|
19
|
-
aws_bedrock = "system.aws.bedrock"
|
|
15
|
+
class PayiCategories:
|
|
16
|
+
anthropic:str = "system.anthropic"
|
|
17
|
+
openai:str = "system.openai"
|
|
18
|
+
azure_openai:str = "system.azureopenai"
|
|
19
|
+
aws_bedrock:str = "system.aws.bedrock"
|
|
20
20
|
|
|
21
21
|
def create_limit_header_from_ids(limit_ids: List[str]) -> Dict[str, str]:
|
|
22
22
|
if not isinstance(limit_ids, list): # type: ignore
|
payi/lib/instrument.py
CHANGED
|
@@ -41,7 +41,7 @@ class PayiInstrumentor:
|
|
|
41
41
|
self,
|
|
42
42
|
payi: Optional[Payi],
|
|
43
43
|
apayi: Optional[AsyncPayi],
|
|
44
|
-
instruments: Union[Set[
|
|
44
|
+
instruments: Union[Set[str], None] = None,
|
|
45
45
|
log_prompt_and_response: bool = True,
|
|
46
46
|
prompt_and_response_logger: Optional[
|
|
47
47
|
Callable[[str, "dict[str, str]"], None]
|
|
@@ -56,7 +56,7 @@ class PayiInstrumentor:
|
|
|
56
56
|
self._blocked_limits: set[str] = set()
|
|
57
57
|
self._exceeded_limits: set[str] = set()
|
|
58
58
|
|
|
59
|
-
if instruments is None:
|
|
59
|
+
if instruments is None or "*" in instruments:
|
|
60
60
|
self._instrument_all()
|
|
61
61
|
else:
|
|
62
62
|
self._instrument_specific(instruments)
|
|
@@ -66,7 +66,7 @@ class PayiInstrumentor:
|
|
|
66
66
|
self._instrument_anthropic()
|
|
67
67
|
self._instrument_aws_bedrock()
|
|
68
68
|
|
|
69
|
-
def _instrument_specific(self, instruments: Set[
|
|
69
|
+
def _instrument_specific(self, instruments: Set[str]) -> None:
|
|
70
70
|
if PayiCategories.openai in instruments or PayiCategories.azure_openai in instruments:
|
|
71
71
|
self._instrument_openai()
|
|
72
72
|
if PayiCategories.anthropic in instruments:
|
|
@@ -375,14 +375,18 @@ class PayiInstrumentor:
|
|
|
375
375
|
if len(ingest_extra_headers) > 0:
|
|
376
376
|
ingest["provider_request_headers"] = [PayICommonModelsAPIRouterHeaderInfoParam(name=k, value=v) for k, v in ingest_extra_headers.items()]
|
|
377
377
|
|
|
378
|
-
provider_prompt = {}
|
|
378
|
+
provider_prompt: "dict[str, Any]" = {}
|
|
379
379
|
for k, v in kwargs.items():
|
|
380
380
|
if k == "messages":
|
|
381
381
|
provider_prompt[k] = [m.model_dump() if hasattr(m, "model_dump") else m for m in v]
|
|
382
382
|
elif k in ["extra_headers", "extra_query"]:
|
|
383
383
|
pass
|
|
384
384
|
else:
|
|
385
|
-
|
|
385
|
+
try:
|
|
386
|
+
json.dumps(v)
|
|
387
|
+
provider_prompt[k] = v
|
|
388
|
+
except (TypeError, ValueError):
|
|
389
|
+
pass
|
|
386
390
|
|
|
387
391
|
if self._log_prompt_and_response:
|
|
388
392
|
ingest["provider_request_json"] = json.dumps(provider_prompt)
|
|
@@ -420,18 +424,28 @@ class PayiInstrumentor:
|
|
|
420
424
|
ingest: IngestUnitsParams = {"category": category, "units": {}} # type: ignore
|
|
421
425
|
ingest["resource"] = kwargs.get("model", "")
|
|
422
426
|
|
|
423
|
-
if category ==
|
|
427
|
+
if category == PayiCategories.openai and instance and hasattr(instance, "_client"):
|
|
424
428
|
from .OpenAIInstrumentor import OpenAiInstrumentor # noqa: I001
|
|
425
429
|
|
|
426
430
|
if OpenAiInstrumentor.is_azure(instance):
|
|
427
|
-
|
|
428
|
-
|
|
431
|
+
route_as_resource = extra_headers.pop(PayiHeaderNames.route_as_resource, None)
|
|
432
|
+
resource_scope = extra_headers.pop(PayiHeaderNames.resource_scope, None)
|
|
433
|
+
|
|
434
|
+
if not route_as_resource:
|
|
429
435
|
logging.error("Azure OpenAI route as resource not found, not ingesting")
|
|
430
436
|
return await wrapped(*args, **kwargs)
|
|
431
437
|
|
|
432
|
-
|
|
438
|
+
if resource_scope:
|
|
439
|
+
if not(resource_scope in ["global", "datazone"] or resource_scope.startswith("region")):
|
|
440
|
+
logging.error("Azure OpenAI invalid resource scope, not ingesting")
|
|
441
|
+
return wrapped(*args, **kwargs)
|
|
442
|
+
|
|
443
|
+
ingest["resource_scope"] = resource_scope
|
|
444
|
+
|
|
445
|
+
category = PayiCategories.azure_openai
|
|
446
|
+
|
|
433
447
|
ingest["category"] = category
|
|
434
|
-
ingest["resource"] =
|
|
448
|
+
ingest["resource"] = route_as_resource
|
|
435
449
|
|
|
436
450
|
current_frame = inspect.currentframe()
|
|
437
451
|
# f_back excludes the current frame, strip() cleans up whitespace and newlines
|
|
@@ -511,7 +525,7 @@ class PayiInstrumentor:
|
|
|
511
525
|
) -> Any:
|
|
512
526
|
context = self.get_context()
|
|
513
527
|
|
|
514
|
-
is_bedrock:bool = category ==
|
|
528
|
+
is_bedrock:bool = category == PayiCategories.aws_bedrock
|
|
515
529
|
|
|
516
530
|
if not context:
|
|
517
531
|
if is_bedrock:
|
|
@@ -539,17 +553,28 @@ class PayiInstrumentor:
|
|
|
539
553
|
else:
|
|
540
554
|
ingest["resource"] = kwargs.get("model", "")
|
|
541
555
|
|
|
542
|
-
if category ==
|
|
543
|
-
from .OpenAIInstrumentor import OpenAiInstrumentor
|
|
556
|
+
if category == PayiCategories.openai and instance and hasattr(instance, "_client"):
|
|
557
|
+
from .OpenAIInstrumentor import OpenAiInstrumentor # noqa: I001
|
|
558
|
+
|
|
544
559
|
if OpenAiInstrumentor.is_azure(instance):
|
|
545
|
-
|
|
546
|
-
|
|
560
|
+
route_as_resource:str = extra_headers.pop(PayiHeaderNames.route_as_resource, None)
|
|
561
|
+
resource_scope:str = extra_headers.pop(PayiHeaderNames.resource_scope, None)
|
|
562
|
+
|
|
563
|
+
if not route_as_resource:
|
|
547
564
|
logging.error("Azure OpenAI route as resource not found, not ingesting")
|
|
548
565
|
return wrapped(*args, **kwargs)
|
|
549
566
|
|
|
550
|
-
|
|
567
|
+
if resource_scope:
|
|
568
|
+
if not(resource_scope in ["global", "datazone"] or resource_scope.startswith("region")):
|
|
569
|
+
logging.error("Azure OpenAI invalid resource scope, not ingesting")
|
|
570
|
+
return wrapped(*args, **kwargs)
|
|
571
|
+
|
|
572
|
+
ingest["resource_scope"] = resource_scope
|
|
573
|
+
|
|
574
|
+
category = PayiCategories.azure_openai
|
|
575
|
+
|
|
551
576
|
ingest["category"] = category
|
|
552
|
-
ingest["resource"] =
|
|
577
|
+
ingest["resource"] = route_as_resource
|
|
553
578
|
|
|
554
579
|
current_frame = inspect.currentframe()
|
|
555
580
|
# f_back excludes the current frame, strip() cleans up whitespace and newlines
|
|
@@ -864,7 +889,7 @@ _instrumentor: Optional[PayiInstrumentor] = None
|
|
|
864
889
|
|
|
865
890
|
def payi_instrument(
|
|
866
891
|
payi: Optional[Union[Payi, AsyncPayi, 'list[Union[Payi, AsyncPayi]]']] = None,
|
|
867
|
-
instruments: Optional[Set[
|
|
892
|
+
instruments: Optional[Set[str]] = None,
|
|
868
893
|
log_prompt_and_response: bool = True,
|
|
869
894
|
prompt_and_response_logger: Optional[Callable[[str, "dict[str, str]"], None]] = None,
|
|
870
895
|
) -> None:
|
payi/resources/ingest.py
CHANGED
|
@@ -101,11 +101,12 @@ class IngestResource(SyncAPIResource):
|
|
|
101
101
|
provider_response_json: Union[str, List[str], None] | NotGiven = NOT_GIVEN,
|
|
102
102
|
provider_uri: Optional[str] | NotGiven = NOT_GIVEN,
|
|
103
103
|
time_to_first_token_ms: Optional[int] | NotGiven = NOT_GIVEN,
|
|
104
|
-
limit_ids:
|
|
105
|
-
request_tags:
|
|
106
|
-
experience_id:
|
|
107
|
-
experience_name:
|
|
108
|
-
user_id:
|
|
104
|
+
limit_ids: Optional[list[str]] | NotGiven = NOT_GIVEN,
|
|
105
|
+
request_tags: Optional[list[str]] | NotGiven = NOT_GIVEN,
|
|
106
|
+
experience_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
107
|
+
experience_name: Optional[str] | NotGiven = NOT_GIVEN,
|
|
108
|
+
user_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
109
|
+
resource_scope: Optional[str] | NotGiven = NOT_GIVEN,
|
|
109
110
|
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
110
111
|
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
111
112
|
extra_headers: Headers | None = None,
|
|
@@ -136,6 +137,8 @@ class IngestResource(SyncAPIResource):
|
|
|
136
137
|
experience_id (str, optional): The experience instance id
|
|
137
138
|
|
|
138
139
|
user_id (str, optional): The user id
|
|
140
|
+
|
|
141
|
+
resource_scope(str, optional): The scope of the resource
|
|
139
142
|
|
|
140
143
|
extra_headers (Dict[str, str], optional): Additional headers for the request. Defaults to None.
|
|
141
144
|
|
|
@@ -176,17 +179,17 @@ class IngestResource(SyncAPIResource):
|
|
|
176
179
|
user_id = NOT_GIVEN
|
|
177
180
|
|
|
178
181
|
extra_headers = {
|
|
179
|
-
**strip_not_given(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
),
|
|
182
|
+
**{key: value for key, value in strip_not_given({
|
|
183
|
+
"xProxy-Limit-IDs": valid_ids_str,
|
|
184
|
+
"xProxy-Request-Tags": valid_tags_str,
|
|
185
|
+
"xProxy-Experience-Name": experience_name,
|
|
186
|
+
"xProxy-Experience-Id": experience_id,
|
|
187
|
+
"xProxy-User-ID": user_id,
|
|
188
|
+
"xProxy-Resource-Scope": resource_scope,
|
|
189
|
+
}).items() if value is not None}, # Ensure no 'None' values are included
|
|
188
190
|
**(extra_headers or {}),
|
|
189
191
|
}
|
|
192
|
+
|
|
190
193
|
return self._post(
|
|
191
194
|
"/api/v1/ingest",
|
|
192
195
|
body=maybe_transform(
|
|
@@ -286,11 +289,12 @@ class AsyncIngestResource(AsyncAPIResource):
|
|
|
286
289
|
provider_response_json: Union[str, List[str], None] | NotGiven = NOT_GIVEN,
|
|
287
290
|
provider_uri: Optional[str] | NotGiven = NOT_GIVEN,
|
|
288
291
|
time_to_first_token_ms: Optional[int] | NotGiven = NOT_GIVEN,
|
|
289
|
-
limit_ids:
|
|
290
|
-
request_tags:
|
|
291
|
-
experience_name:
|
|
292
|
-
experience_id:
|
|
293
|
-
user_id:
|
|
292
|
+
limit_ids: Optional[list[str]] | NotGiven = NOT_GIVEN,
|
|
293
|
+
request_tags: Optional[list[str]] | NotGiven = NOT_GIVEN,
|
|
294
|
+
experience_name: Optional[str] | NotGiven = NOT_GIVEN,
|
|
295
|
+
experience_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
296
|
+
user_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
297
|
+
resource_scope: Union[str, None] | NotGiven = NOT_GIVEN,
|
|
294
298
|
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
295
299
|
extra_headers: Headers | None = None,
|
|
296
300
|
extra_query: Query | None = None,
|
|
@@ -320,6 +324,8 @@ class AsyncIngestResource(AsyncAPIResource):
|
|
|
320
324
|
experience_id (str, optional): The experience instance id
|
|
321
325
|
|
|
322
326
|
user_id (str, optional): The user id
|
|
327
|
+
|
|
328
|
+
resource_scope (str, optional): The scope of the resource
|
|
323
329
|
|
|
324
330
|
extra_headers (Dict[str, str], optional): Additional headers for the request. Defaults to None.
|
|
325
331
|
|
|
@@ -360,15 +366,14 @@ class AsyncIngestResource(AsyncAPIResource):
|
|
|
360
366
|
user_id = NOT_GIVEN
|
|
361
367
|
|
|
362
368
|
extra_headers = {
|
|
363
|
-
**strip_not_given(
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
),
|
|
369
|
+
**{key: value for key, value in strip_not_given({
|
|
370
|
+
"xProxy-Limit-IDs": valid_ids_str,
|
|
371
|
+
"xProxy-Request-Tags": valid_tags_str,
|
|
372
|
+
"xProxy-Experience-Name": experience_name,
|
|
373
|
+
"xProxy-Experience-Id": experience_id,
|
|
374
|
+
"xProxy-User-ID": user_id,
|
|
375
|
+
"xProxy-Resource-Scope": resource_scope,
|
|
376
|
+
}).items() if value is not None}, # Ensure no 'None' values are included
|
|
372
377
|
**(extra_headers or {}),
|
|
373
378
|
}
|
|
374
379
|
return await self._post(
|
payi/types/ingest_event_param.py
CHANGED
|
@@ -51,6 +51,8 @@ class IngestUnitsParams(TypedDict, total=False):
|
|
|
51
51
|
|
|
52
52
|
experience_id: Annotated[Union[str, None], PropertyInfo(alias="xProxy-Experience-Id")]
|
|
53
53
|
|
|
54
|
+
resource_scope: Annotated[Union[str, None], PropertyInfo(alias="xProxy-Resource-Scope")]
|
|
55
|
+
|
|
54
56
|
user_id: Annotated[Union[str, None], PropertyInfo(alias="xProxy-User-ID")]
|
|
55
57
|
|
|
56
58
|
|
|
@@ -11,7 +11,7 @@ payi/_resource.py,sha256=j2jIkTr8OIC8sU6-05nxSaCyj4MaFlbZrwlyg4_xJos,1088
|
|
|
11
11
|
payi/_response.py,sha256=CfrNS_3wbL8o9dRyRVfZQ5E1GUlA4CUIUEK8olmfGqE,28777
|
|
12
12
|
payi/_streaming.py,sha256=Z_wIyo206T6Jqh2rolFg2VXZgX24PahLmpURp0-NssU,10092
|
|
13
13
|
payi/_types.py,sha256=2mbMK86K3W1aMTW7sOGQ-VND6-A2IuXKm8p4sYFztBU,6141
|
|
14
|
-
payi/_version.py,sha256=
|
|
14
|
+
payi/_version.py,sha256=8EiC_xRCoylkMdtygYL1cGog4vO86O8lPQot0lXlxNU,165
|
|
15
15
|
payi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
payi/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
|
|
17
17
|
payi/_utils/_logs.py,sha256=fmnf5D9TOgkgZKfgYmSa3PiUc3SZgkchn6CzJUeo0SQ,768
|
|
@@ -27,11 +27,11 @@ payi/lib/AnthropicInstrumentor.py,sha256=h-yebG7r7cSRVM_utva55Gc4BVcoW6WGrQrDg55
|
|
|
27
27
|
payi/lib/BedrockInstrumentor.py,sha256=4WSZLzLHMv-5U1OFr0ZErESNHTyPHn0kHATUw4HTDkQ,10072
|
|
28
28
|
payi/lib/OpenAIInstrumentor.py,sha256=ZUu-Byhz7AXhvxjOMdX8tB2JOpM5sCj0KnyRB49lQg0,6881
|
|
29
29
|
payi/lib/Stopwatch.py,sha256=7OJlxvr2Jyb6Zr1LYCYKczRB7rDVKkIR7gc4YoleNdE,764
|
|
30
|
-
payi/lib/helpers.py,sha256=
|
|
31
|
-
payi/lib/instrument.py,sha256=
|
|
30
|
+
payi/lib/helpers.py,sha256=ghW4v_ZmCfy4ImGJr1PFTPfzHYwCCtdtyq9UqKwxpGc,2967
|
|
31
|
+
payi/lib/instrument.py,sha256=Fk-Vh9NEhfp6UNaTAkkEgL5Kiq7nFPDwUT-EuzCMF5Y,37443
|
|
32
32
|
payi/resources/__init__.py,sha256=isHGXSl9kOrZDduKrX3UenTwrdTpuKJVBjw6NYSBV20,3592
|
|
33
33
|
payi/resources/billing_models.py,sha256=5w3RfGXtGlyq5vbTw6hQrx1UlzRBtlq8ArcFlf5e3TY,20152
|
|
34
|
-
payi/resources/ingest.py,sha256=
|
|
34
|
+
payi/resources/ingest.py,sha256=RFfN1hwUngFgHJNcMaqZ1C6Xw1Qdve81dtUgjJSOb_A,19159
|
|
35
35
|
payi/resources/price_modifiers.py,sha256=t-k2F_zf2FhoxiqDHAPBPvhSgTjewlJqh50y58FNMuw,13475
|
|
36
36
|
payi/resources/categories/__init__.py,sha256=w5gMiPdBSzJA_qfoVtFBElaoe8wGf_O63R7R1Spr6Gk,1093
|
|
37
37
|
payi/resources/categories/categories.py,sha256=FohmajDcadMXzhG3Z1HKGkbSImO7rhzQ0olZXHz8z48,16074
|
|
@@ -66,9 +66,9 @@ payi/types/cost_details.py,sha256=w9p79opEG3kcsjkRRP7niaMcUswdfB4Y7HCkVTcQ1zQ,30
|
|
|
66
66
|
payi/types/default_response.py,sha256=o617LpRsCIZHCZxAc5nVI2JQ3HPGZo4gCDvSDkxkIJ8,270
|
|
67
67
|
payi/types/experience_instance_response.py,sha256=N07MH6hjs1ISHLVpR2FG-u4awsZ_GGi97UNMXAWV1yA,296
|
|
68
68
|
payi/types/ingest_bulk_params.py,sha256=d76YwiXaNeltLS3w86ZxLzTKGa7ymGLJDSelaMQGf8Y,382
|
|
69
|
-
payi/types/ingest_event_param.py,sha256=
|
|
69
|
+
payi/types/ingest_event_param.py,sha256=1-pr5wMiWXAGDqBmQHKdpHJy0Fk9vOQl7XTGLtcjtdI,1507
|
|
70
70
|
payi/types/ingest_response.py,sha256=KZfsgUhC942QkkjDFMqjJwCRoO2vkXv-Sx3X_xjijfg,1449
|
|
71
|
-
payi/types/ingest_units_params.py,sha256=
|
|
71
|
+
payi/types/ingest_units_params.py,sha256=QrfkSW-tFDKpn8cPbbyAOhM17W1prC-aJeXMFeGiqJI,1884
|
|
72
72
|
payi/types/limit_create_params.py,sha256=Av8oMCxlKH7VB2MtYN5-25rAjqDDTPHjsXIQ2xubmck,549
|
|
73
73
|
payi/types/limit_history_response.py,sha256=sCx2qKBiHU9X2KrYWV8NZiarYMGurof5GF4QobR2-EU,787
|
|
74
74
|
payi/types/limit_list_params.py,sha256=iWM67oL53y2IZ7D3Gyy8mdYv-B7vF-rbmRFn7SBUnJk,364
|
|
@@ -112,7 +112,7 @@ payi/types/requests/request_result.py,sha256=phYQiqhwNaR9igP-Fhs34Y-__dlT7L4wq-r
|
|
|
112
112
|
payi/types/shared/__init__.py,sha256=-xz5dxK5LBjLnsi2LpLq5btaGDFp-mSjJ0y2qKy0Yus,264
|
|
113
113
|
payi/types/shared/evaluation_response.py,sha256=ejEToMA57PUu1SldEtJ5z9r4fAO3U0tvdjbsyIoVX1s,214
|
|
114
114
|
payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py,sha256=XmIzJXy4zAi-mfrDvEXiYjO3qF1EvugGUl-Gijj4TA4,268
|
|
115
|
-
payi-0.1.
|
|
116
|
-
payi-0.1.
|
|
117
|
-
payi-0.1.
|
|
118
|
-
payi-0.1.
|
|
115
|
+
payi-0.1.0a52.dist-info/METADATA,sha256=uBhSl9Hp-zULHZsstIS7MVDPGcLbrVTE_0Zd3ZFzxvA,12660
|
|
116
|
+
payi-0.1.0a52.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
117
|
+
payi-0.1.0a52.dist-info/licenses/LICENSE,sha256=CQt03aM-P4a3Yg5qBg3JSLVoQS3smMyvx7tYg_6V7Gk,11334
|
|
118
|
+
payi-0.1.0a52.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|