wip
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
import os
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import boto3
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mypy_boto3_dynamodb.client import DynamoDBClient
|
||||
else:
|
||||
DynamoDBClient = object
|
||||
|
||||
def get_dynamodb_client():
|
||||
running_sam_local = os.getenv('AWS_SAM_LOCAL')
|
||||
|
||||
if os.getenv('AWS_LAMBDA_FUNCTION_NAME') and not running_sam_local:
|
||||
def get_dynamodb_client() -> DynamoDBClient:
|
||||
if os.getenv('AWS_LAMBDA_FUNCTION_NAME'):
|
||||
return boto3.client('dynamodb')
|
||||
|
||||
dockerhost = 'host.docker.internal'
|
||||
localhost = '127.0.0.1'
|
||||
host = dockerhost if running_sam_local else localhost
|
||||
|
||||
return boto3.client('dynamodb', endpoint_url=f'http://{host}:8000')
|
||||
return boto3.client('dynamodb', endpoint_url='http://127.0.0.1:8000')
|
||||
|
||||
|
||||
dynamodb_client = get_dynamodb_client()
|
||||
dynamodb_client: DynamoDBClient = get_dynamodb_client()
|
||||
|
||||
@@ -157,7 +157,6 @@ class AuthorizationServer(oauth2.AuthorizationServer):
|
||||
body,
|
||||
headers,
|
||||
):
|
||||
logger.debug('handle_response', status=status, body=body)
|
||||
return Response(
|
||||
status_code=status,
|
||||
body=body,
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
import { isbot } from "isbot";
|
||||
import { renderToReadableStream } from "react-dom/server";
|
||||
import type { AppLoadContext, EntryContext } from "react-router";
|
||||
import { ServerRouter } from "react-router";
|
||||
import { isbot } from 'isbot'
|
||||
import { renderToReadableStream } from 'react-dom/server'
|
||||
import type { AppLoadContext, EntryContext } from 'react-router'
|
||||
import { ServerRouter } from 'react-router'
|
||||
|
||||
export default async function handleRequest(
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
routerContext: EntryContext,
|
||||
_loadContext: AppLoadContext,
|
||||
_loadContext: AppLoadContext
|
||||
) {
|
||||
let shellRendered = false;
|
||||
const userAgent = request.headers.get("user-agent");
|
||||
let shellRendered = false
|
||||
const userAgent = request.headers.get('user-agent')
|
||||
|
||||
const body = await renderToReadableStream(
|
||||
<ServerRouter context={routerContext} url={request.url} />,
|
||||
{
|
||||
onError(error: unknown) {
|
||||
responseStatusCode = 500;
|
||||
responseStatusCode = 500
|
||||
// Log streaming rendering errors from inside the shell. Don't log
|
||||
// errors encountered during initial shell rendering since they'll
|
||||
// reject and get logged in handleDocumentRequest.
|
||||
if (shellRendered) {
|
||||
console.error(error);
|
||||
console.error(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
shellRendered = true;
|
||||
}
|
||||
}
|
||||
)
|
||||
shellRendered = true
|
||||
|
||||
// Ensure requests from bots and SPA Mode renders wait for all content to load before responding
|
||||
// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
|
||||
if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) {
|
||||
await body.allReady;
|
||||
await body.allReady
|
||||
}
|
||||
|
||||
responseHeaders.set("Content-Type", "text/html");
|
||||
responseHeaders.set('Content-Type', 'text/html')
|
||||
return new Response(body, {
|
||||
headers: responseHeaders,
|
||||
status: responseStatusCode,
|
||||
});
|
||||
status: responseStatusCode
|
||||
})
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function Index({}: Route.ComponentProps) {
|
||||
<div className="w-full max-w-xs grid gap-6">
|
||||
<div className="flex justify-center">
|
||||
<div className="border border-white/15 bg-white/5 px-2.5 py-3 rounded-xl">
|
||||
<img src={logo} alt="React Router" className="block size-12" />
|
||||
<img src={logo} alt="EDUSEG®" className="block size-12" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = ""
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"layercake",
|
||||
]
|
||||
dependencies = ["layercake"]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
@@ -14,6 +12,7 @@ dev = [
|
||||
"pytest>=8.4.1",
|
||||
"ruff>=0.12.1",
|
||||
"pytest-cov>=6.2.1",
|
||||
"boto3-stubs[essential]>=1.40.44",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import json
|
||||
import pprint
|
||||
from base64 import b64encode
|
||||
from http import HTTPMethod, HTTPStatus
|
||||
from urllib.parse import urlencode
|
||||
@@ -44,7 +43,7 @@ def token(
|
||||
return json.loads(r['body'])
|
||||
|
||||
|
||||
def test_token(
|
||||
def test_revoke(
|
||||
app,
|
||||
token,
|
||||
seeds,
|
||||
|
||||
@@ -7,6 +7,10 @@ from layercake.dynamodb import DynamoDBPersistenceLayer
|
||||
|
||||
from ..conftest import HttpApiProxy, LambdaContext
|
||||
|
||||
CLIENT_ID = 'd72d4005-1fa7-4430-9754-80d5e2487bb6'
|
||||
CLIENT_SECRET = '1nFD8alDbGHgc3g1RLY960xyRJVee0SlMoIB0MUlSuiJy28W'
|
||||
AUTH = b64encode(f'{CLIENT_ID}:{CLIENT_SECRET}'.encode()).decode()
|
||||
|
||||
|
||||
def test_token(
|
||||
app,
|
||||
@@ -91,22 +95,19 @@ def test_refresh_token(
|
||||
http_api_proxy: HttpApiProxy,
|
||||
lambda_context: LambdaContext,
|
||||
):
|
||||
client_id = 'd72d4005-1fa7-4430-9754-80d5e2487bb6'
|
||||
client_secret = '1nFD8alDbGHgc3g1RLY960xyRJVee0SlMoIB0MUlSuiJy28W'
|
||||
auth = b64encode(f'{client_id}:{client_secret}'.encode()).decode()
|
||||
r = app.lambda_handler(
|
||||
http_api_proxy(
|
||||
raw_path='/token',
|
||||
method=HTTPMethod.POST,
|
||||
headers={
|
||||
'Authorization': f'Basic {auth}',
|
||||
'Authorization': f'Basic {AUTH}',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body=urlencode(
|
||||
{
|
||||
'grant_type': 'refresh_token',
|
||||
'refresh_token': 'CyF3Ik3b9hMIo3REVv27gZAHd7dvwZq6QrkhWr7qHEen4UVy',
|
||||
'client_id': client_id,
|
||||
'client_id': CLIENT_ID,
|
||||
}
|
||||
),
|
||||
),
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
// User data
|
||||
{"id": "357db1c5-7442-4075-98a3-fbe5c938a419", "sk": "0", "name": "Sérgio R Siqueira", "email": "sergio@somosbeta.com.br"}
|
||||
// {"id": "357db1c5-7442-4075-98a3-fbe5c938a419", "sk": "PASSWORD", "hash": "$pbkdf2-sha256$29000$IuTcm7M2BiAEgPB.b.3dGw$d8xVCbx8zxg7MeQBrOvCOgniiilsIHEMHzoH/OXftLQ"}
|
||||
{"id": "357db1c5-7442-4075-98a3-fbe5c938a419", "sk": "PASSWORD", "hash": "$pbkdf2-sha256$29000$IuTcm7M2BiAEgPB.b.3dGw$d8xVCbx8zxg7MeQBrOvCOgniiilsIHEMHzoH/OXftLQ"}
|
||||
{"id": "357db1c5-7442-4075-98a3-fbe5c938a419", "sk": "SCOPE", "scope": "openid profile email offline_access read:users read:courses"}
|
||||
{"id": "357db1c5-7442-4075-98a3-fbe5c938a419", "sk": "SESSION#36af142e-9f6d-49d3-bfe9-6a6bd6ab2712", "created_at": "2025-09-17T13:44:34.544491-03:00", "ttl": 1760719474}
|
||||
|
||||
|
||||
119
id.saladeaula.digital/uv.lock
generated
119
id.saladeaula.digital/uv.lock
generated
@@ -119,6 +119,30 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/13/0eb850c821a976346a905370bb30c86da7edc2bbc3977c445fffc6306032/boto3-1.38.46-py3-none-any.whl", hash = "sha256:9c8e88a32a6465e5905308708cff5b17547117f06982908bdfdb0108b4a65079", size = 139925, upload-time = "2025-06-27T20:18:15.366Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boto3-stubs"
|
||||
version = "1.40.44"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "botocore-stubs" },
|
||||
{ name = "types-s3transfer" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/56/65/7996dd7e6035ea8ede82169403a7f0a6e5a60fadbd79ecfd042b62dc888f/boto3_stubs-1.40.44.tar.gz", hash = "sha256:c49030d3c8a1f719e2ea283d7eff834037406ef41ecad47490d780ae8a15ff5c", size = 100839, upload-time = "2025-10-02T20:37:35.47Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/24/79/e389dd7ca833f93c06921c2d57650784446c9a18aea091dd8dd1ee25ee23/boto3_stubs-1.40.44-py3-none-any.whl", hash = "sha256:0fa09cca77e4b3be0222ece396ef8eb99cfb495e48e8b33c8e497d910597e376", size = 69687, upload-time = "2025-10-02T20:37:30.366Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
essential = [
|
||||
{ name = "mypy-boto3-cloudformation" },
|
||||
{ name = "mypy-boto3-dynamodb" },
|
||||
{ name = "mypy-boto3-ec2" },
|
||||
{ name = "mypy-boto3-lambda" },
|
||||
{ name = "mypy-boto3-rds" },
|
||||
{ name = "mypy-boto3-s3" },
|
||||
{ name = "mypy-boto3-sqs" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "botocore"
|
||||
version = "1.38.46"
|
||||
@@ -133,6 +157,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/00/dd90b7a0255587ba1c9754d32a221adb4a9022f181df3eef401b0b9fadfc/botocore-1.38.46-py3-none-any.whl", hash = "sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b", size = 13736872, upload-time = "2025-06-27T20:18:00.901Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "botocore-stubs"
|
||||
version = "1.40.33"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "types-awscrt" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ae/94/16f8e1f41feaa38f1350aa5a4c60c5724b6c8524ca0e6c28523bf5070e74/botocore_stubs-1.40.33.tar.gz", hash = "sha256:89c51ae0b28d9d79fde8c497cf908ddf872ce027d2737d4d4ba473fde9cdaa82", size = 42742, upload-time = "2025-09-17T20:25:56.388Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/af/7b/6d8fe12a955b16094460e89ea7c4e063f131f4b3bd461b96bcd625d0c79e/botocore_stubs-1.40.33-py3-none-any.whl", hash = "sha256:ad21fee32cbdc7ad4730f29baf88424c7086bf88a745f8e43660ca3e9a7e5f89", size = 66843, upload-time = "2025-09-17T20:25:54.052Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "camel-converter"
|
||||
version = "4.0.1"
|
||||
@@ -387,6 +423,7 @@ dependencies = [
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "boto3-stubs", extra = ["essential"] },
|
||||
{ name = "jsonlines" },
|
||||
{ name = "pytest" },
|
||||
{ name = "pytest-cov" },
|
||||
@@ -398,6 +435,7 @@ requires-dist = [{ name = "layercake", directory = "../layercake" }]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "boto3-stubs", extras = ["essential"], specifier = ">=1.40.44" },
|
||||
{ name = "jsonlines", specifier = ">=4.0.0" },
|
||||
{ name = "pytest", specifier = ">=8.4.1" },
|
||||
{ name = "pytest-cov", specifier = ">=6.2.1" },
|
||||
@@ -528,6 +566,69 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/fb/cbc1247429269460e5eb762a798beb702953673d88ce87a26a21263a44d8/meilisearch-0.36.0-py3-none-any.whl", hash = "sha256:f3f0882da7531c038fc6698f18fa492c7d46f8e238600a5af9eb627c7ff21d9e", size = 27666, upload-time = "2025-06-20T02:14:09.268Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-cloudformation"
|
||||
version = "1.40.44"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8c/2c/140b6b0d74afa4854edb3b3e640ff96c711270f27711ad1325cecc5661c1/mypy_boto3_cloudformation-1.40.44.tar.gz", hash = "sha256:3d82f5504382c86ad195a1b80a2a82f73587c37e1b636864ebb85dd43bd79a5b", size = 57870, upload-time = "2025-10-02T20:32:01.1Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/38/12301080cc5004593b8593c0cc7404c13d702ac1c15d4e0ccfacd1f4f416/mypy_boto3_cloudformation-1.40.44-py3-none-any.whl", hash = "sha256:64c8fe58ab7661fbb0bdea07c7375d3ebc3875760140feb6ad8f591a08a22647", size = 69896, upload-time = "2025-10-02T20:31:56.896Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-dynamodb"
|
||||
version = "1.40.44"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0a/63/31bc3e1d890541284df0d5569e61398d563c1982724ec4f19c08142e7048/mypy_boto3_dynamodb-1.40.44.tar.gz", hash = "sha256:58fa3a638b1caef5644b60f5894e1182a2951feb30a3dc6dedb34e1b0c9ded99", size = 47947, upload-time = "2025-10-02T20:37:27.963Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/52/1e6230eab337062f19fcfe1bd39cff0cc841b9a48c37318fd2b4d66b07a3/mypy_boto3_dynamodb-1.40.44-py3-none-any.whl", hash = "sha256:ab978a9d24997d513c5e35bf4aae9b3dfe4f8482a13799180ecefbb1dc93d271", size = 56994, upload-time = "2025-10-02T20:31:56.823Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-ec2"
|
||||
version = "1.40.40"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e7/e0/390fa5c21fd96d9aafdd2174b3522bad867f852b2fcc3900d8c196ad8f26/mypy_boto3_ec2-1.40.40.tar.gz", hash = "sha256:23e60e95a0e14c814dddf77c7f931cb4c10511034a47e972313c8f5e23ea691a", size = 409172, upload-time = "2025-09-26T19:25:12.05Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/48/36/46db406bbc399d17f5ad17d71f68978a5f33d4772183c386a95ab3f5a8e9/mypy_boto3_ec2-1.40.40-py3-none-any.whl", hash = "sha256:4ffc151d4a411f6805e87656c567fdeb5c95728636c4912d7faf4ab476adf24a", size = 398392, upload-time = "2025-09-26T19:25:08.854Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-lambda"
|
||||
version = "1.40.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/25/4f/63def7a5be630e8d39186594b01fee86f2e6dcbca3e0b0e80a3ea90bc4ae/mypy_boto3_lambda-1.40.7.tar.gz", hash = "sha256:e8bedf03a67fade5db861fe902df063064292352eed5f785f74cd0e591948db9", size = 42491, upload-time = "2025-08-11T19:30:54.805Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/ef/ab7a0fc83b8f3c39145cbce4a8bf5326e153157f0edcc939b4570e0b9f9e/mypy_boto3_lambda-1.40.7-py3-none-any.whl", hash = "sha256:398c9dd051278430168e907b6b6c2078a3a1bca3948c2bf4d47eda8d7da28573", size = 49058, upload-time = "2025-08-11T19:30:51.675Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-rds"
|
||||
version = "1.40.42"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ad/de/a4bace6b75251c79fdefa0335c72c86ee68e2c0bfdb1aef36607241365bc/mypy_boto3_rds-1.40.42.tar.gz", hash = "sha256:77d8ce076a42400f87154c4e0c4c298358cbb12bc6a02ec41fb6daa97539d132", size = 85576, upload-time = "2025-09-30T19:43:21.72Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/5b/902fade65a8de58c08895f4a54a524a068eb25bedffa32564e7ba8959f1d/mypy_boto3_rds-1.40.42-py3-none-any.whl", hash = "sha256:686f5fd95de3efc3b0a041e3bbd3304d5674703d36adeb944f3888207019b0f8", size = 92009, upload-time = "2025-09-30T19:43:17.856Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-s3"
|
||||
version = "1.40.26"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/00/b8/55d21ed9ca479df66d9892212ba7d7977850ef17aa80a83e3f11f31190fd/mypy_boto3_s3-1.40.26.tar.gz", hash = "sha256:8d2bfd1052894d0e84c9fb9358d838ba0eed0265076c7dd7f45622c770275c99", size = 75948, upload-time = "2025-09-08T20:12:21.405Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/85/a5/dba3384423834009bdd41c7021de5c663468a0e7bc4071cb301721e52a99/mypy_boto3_s3-1.40.26-py3-none-any.whl", hash = "sha256:6d055d16ef89a0133ade92f6b4f09603e4acc31a0f5e8f846edf4eb48f17b5a7", size = 82762, upload-time = "2025-09-08T20:12:19.338Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-boto3-sqs"
|
||||
version = "1.40.35"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/70/be/27ead4078dc1faa9c6c1916e0f7cfdb102925591eaab153a496640250541/mypy_boto3_sqs-1.40.35.tar.gz", hash = "sha256:c11f95ee72bddb84f7fecf3000372e01547f36737064b785f1cf34191b87e03f", size = 23583, upload-time = "2025-09-19T19:42:27.814Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/26/12/383dbfd97656f0271e4b7f047be211b49ee3daa2d5d78869b8c2993c906b/mypy_boto3_sqs-1.40.35-py3-none-any.whl", hash = "sha256:719967d5973ab99a1298381023add28da45ee0dca2b5bf4969b7b5e4fc1a5db8", size = 33779, upload-time = "2025-09-19T19:42:23.975Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.10.18"
|
||||
@@ -906,6 +1007,24 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-awscrt"
|
||||
version = "0.27.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/56/ce/5d84526a39f44c420ce61b16654193f8437d74b54f21597ea2ac65d89954/types_awscrt-0.27.6.tar.gz", hash = "sha256:9d3f1865a93b8b2c32f137514ac88cb048b5bc438739945ba19d972698995bfb", size = 16937, upload-time = "2025-08-13T01:54:54.659Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/af/e3d20e3e81d235b3964846adf46a334645a8a9b25a0d3d472743eb079552/types_awscrt-0.27.6-py3-none-any.whl", hash = "sha256:18aced46da00a57f02eb97637a32e5894dc5aa3dc6a905ba3e5ed85b9f3c526b", size = 39626, upload-time = "2025-08-13T01:54:53.454Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-s3transfer"
|
||||
version = "0.13.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a5/c5/23946fac96c9dd5815ec97afd1c8ad6d22efa76c04a79a4823f2f67692a5/types_s3transfer-0.13.1.tar.gz", hash = "sha256:ce488d79fdd7d3b9d39071939121eca814ec65de3aa36bdce1f9189c0a61cc80", size = 14181, upload-time = "2025-08-31T16:57:06.93Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/dc/b3f9b5c93eed6ffe768f4972661250584d5e4f248b548029026964373bcd/types_s3transfer-0.13.1-py3-none-any.whl", hash = "sha256:4ff730e464a3fd3785b5541f0f555c1bd02ad408cf82b6b7a95429f6b0d26b4a", size = 19617, upload-time = "2025-08-31T16:57:05.73Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.14.0"
|
||||
|
||||
Reference in New Issue
Block a user