add docs
This commit is contained in:
@@ -13,3 +13,4 @@ if 'PYTEST_VERSION' in os.environ:
|
||||
DYNAMODB_ENDPOINT_URL = 'http://127.0.0.1:8000'
|
||||
|
||||
dynamodb_client = boto3.client('dynamodb', endpoint_url=DYNAMODB_ENDPOINT_URL)
|
||||
idp_client = boto3.client('cognito-idp')
|
||||
|
||||
@@ -57,10 +57,11 @@ class Elastic:
|
||||
index: str,
|
||||
doc: dict,
|
||||
):
|
||||
return self.client.index(
|
||||
return self.client.update(
|
||||
index=index,
|
||||
id=id,
|
||||
document=_serialize_to_basic_types(doc),
|
||||
doc=_serialize_to_basic_types(doc),
|
||||
doc_as_upsert=True,
|
||||
)
|
||||
|
||||
def delete_index(self, index: str) -> bool:
|
||||
@@ -90,12 +91,12 @@ if __name__ == '__main__':
|
||||
|
||||
# Populate DynamoDB tables with data from JSONL files
|
||||
for file in tqdm(jsonl_files, desc='Processing files'):
|
||||
with jsonlines.open(f'seeds/{file}') as lines:
|
||||
with open(f'seeds/{file}') as fp:
|
||||
table_name = file.removesuffix('.jsonl')
|
||||
reader = jsonlines.Reader(fp)
|
||||
reader = jsonlines.Reader(fp).iter(skip_invalid=True)
|
||||
|
||||
for line in tqdm(lines, desc=f'Processing lines in {file}'):
|
||||
put_item(line, table_name, dynamodb_client)
|
||||
for line in tqdm(reader, desc=f'Processing lines in {file}'):
|
||||
put_item(line, table_name, dynamodb_client) # type: ignore
|
||||
|
||||
# Scan DynamoDB tables and index the data into Elasticsearch
|
||||
for file in tqdm(jsonl_files, desc='Scanning tables'):
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
from aws_lambda_powertools import Logger
|
||||
|
||||
logger = Logger(__name__)
|
||||
|
||||
|
||||
class UnauthorizedError(Exception):
|
||||
pass
|
||||
|
||||
@@ -10,3 +15,24 @@ def get_user(access_token: str, /, idp_client) -> dict[str, str]:
|
||||
raise UnauthorizedError()
|
||||
else:
|
||||
return {attr['Name']: attr['Value'] for attr in user['UserAttributes']}
|
||||
|
||||
|
||||
def admin_get_user(
|
||||
sub: str,
|
||||
user_pool_id: str,
|
||||
*,
|
||||
idp_client,
|
||||
) -> dict[str, str] | None:
|
||||
"""Gets the specified user by user name in a user pool as an administrator.
|
||||
Works on any user.
|
||||
|
||||
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp/client/admin_get_user.html
|
||||
- https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminGetUser.html
|
||||
"""
|
||||
try:
|
||||
user = idp_client.admin_get_user(Username=sub, UserPoolId=user_pool_id)
|
||||
except idp_client.exceptions as err:
|
||||
logger.exception(err)
|
||||
return None
|
||||
else:
|
||||
return user
|
||||
|
||||
@@ -10,13 +10,13 @@ def create_course(
|
||||
/,
|
||||
persistence_layer: DynamoDBPersistenceLayer,
|
||||
):
|
||||
current_time = now()
|
||||
now_ = now()
|
||||
transact = TransactItems(persistence_layer.table_name)
|
||||
transact.put(
|
||||
item={
|
||||
'sk': '0',
|
||||
'tenant__org_id': {org.id},
|
||||
'create_date': current_time,
|
||||
'create_date': now_,
|
||||
**course.model_dump(),
|
||||
}
|
||||
)
|
||||
@@ -26,7 +26,7 @@ def create_course(
|
||||
'sk': 'tenant',
|
||||
'org_id': org.id,
|
||||
'name': org.name,
|
||||
'create_date': current_time,
|
||||
'create_date': now_,
|
||||
}
|
||||
)
|
||||
return persistence_layer.transact_write_items(transact)
|
||||
@@ -38,7 +38,7 @@ def update_course(
|
||||
/,
|
||||
persistence_layer: DynamoDBPersistenceLayer,
|
||||
):
|
||||
current_time = now()
|
||||
now_ = now()
|
||||
transact = TransactItems(persistence_layer.table_name)
|
||||
transact.update(
|
||||
key=KeyPair(id, '0'),
|
||||
@@ -50,7 +50,7 @@ def update_course(
|
||||
':name': course.name,
|
||||
':cert': course.cert.model_dump() if course.cert else None,
|
||||
':access_period': course.access_period,
|
||||
':update_date': current_time,
|
||||
':update_date': now_,
|
||||
},
|
||||
cond_expr='attribute_exists(sk)',
|
||||
)
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
import json
|
||||
from typing import Literal
|
||||
from typing import TypedDict
|
||||
|
||||
from aws_lambda_powertools.event_handler.api_gateway import Router
|
||||
from elasticsearch import Elasticsearch
|
||||
from pydantic import BaseModel
|
||||
from layercake.dynamodb import (
|
||||
DynamoDBCollection,
|
||||
DynamoDBPersistenceLayer,
|
||||
SortKey,
|
||||
TransactKey,
|
||||
)
|
||||
from pydantic import UUID4, BaseModel
|
||||
|
||||
import elastic
|
||||
from settings import ELASTIC_CONN, ENROLLMENT_TABLE
|
||||
from boto3clients import dynamodb_client
|
||||
from middlewares.audit_log_middleware import AuditLogMiddleware
|
||||
from middlewares.authorizer_middleware import User
|
||||
from settings import ELASTIC_CONN, ENROLLMENT_TABLE, USER_TABLE
|
||||
|
||||
router = Router()
|
||||
elastic_client = Elasticsearch(**ELASTIC_CONN)
|
||||
enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
|
||||
user_layer = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
|
||||
enrollment_collect = DynamoDBCollection(enrollment_layer)
|
||||
user_collect = DynamoDBCollection(user_layer)
|
||||
|
||||
|
||||
@router.get('/', compress=True, tags=['Enrollment'])
|
||||
@@ -28,16 +41,44 @@ def get_enrollments():
|
||||
|
||||
@router.get('/<id>', compress=True, tags=['Enrollment'])
|
||||
def get_enrollment(id: str):
|
||||
return {}
|
||||
return enrollment_collect.get_items(
|
||||
TransactKey(id)
|
||||
+ SortKey('0')
|
||||
+ SortKey('started_date')
|
||||
+ SortKey('finished_date')
|
||||
+ SortKey('failed_date')
|
||||
+ SortKey('canceled_date')
|
||||
+ SortKey('archived_date')
|
||||
+ SortKey('cancel_policy')
|
||||
+ SortKey('parent_vacancy')
|
||||
+ SortKey('lock', path_spec='hash')
|
||||
+ SortKey('author')
|
||||
+ SortKey('tenant')
|
||||
+ SortKey('cert')
|
||||
)
|
||||
|
||||
|
||||
class CancelPayload(BaseModel):
|
||||
status: Literal['CANCELED'] = 'CANCELED'
|
||||
class Course(TypedDict):
|
||||
id: str
|
||||
name: str
|
||||
|
||||
|
||||
@router.patch('/<id>', compress=True, tags=['Enrollment'])
|
||||
def cancel(id: str, payload: CancelPayload):
|
||||
return {}
|
||||
class Cancel(BaseModel):
|
||||
id: UUID4 | str
|
||||
course: Course
|
||||
|
||||
|
||||
@router.patch(
|
||||
'/<id>/cancel',
|
||||
compress=True,
|
||||
tags=['Enrollment'],
|
||||
middlewares=[
|
||||
AuditLogMiddleware('ENROLLMENT_CANCEL', user_collect, ('id', 'course'))
|
||||
],
|
||||
)
|
||||
def cancel(id: str, payload: Cancel):
|
||||
user: User = router.context['user']
|
||||
return payload
|
||||
|
||||
|
||||
@router.post('/', compress=True, tags=['Enrollment'])
|
||||
|
||||
@@ -22,11 +22,11 @@ LIMIT = 25
|
||||
@router.get('/', include_in_schema=False)
|
||||
def settings():
|
||||
user: User = router.context['user']
|
||||
acls = user_collect.get_items(
|
||||
acls = user_collect.query(
|
||||
KeyPair(user.id, PrefixKey('acls')),
|
||||
limit=LIMIT,
|
||||
)
|
||||
tenants = user_collect.get_items(
|
||||
tenants = user_collect.query(
|
||||
KeyPair(user.id, PrefixKey('orgs')),
|
||||
limit=LIMIT,
|
||||
)
|
||||
|
||||
@@ -21,11 +21,12 @@ from layercake.dynamodb import (
|
||||
)
|
||||
from pydantic import UUID4, BaseModel, StringConstraints
|
||||
|
||||
import cognito
|
||||
import elastic
|
||||
from boto3clients import dynamodb_client
|
||||
from boto3clients import dynamodb_client, idp_client
|
||||
from middlewares import AuditLogMiddleware
|
||||
from models import User
|
||||
from settings import ELASTIC_CONN, USER_TABLE
|
||||
from settings import ELASTIC_CONN, USER_POOOL_ID, USER_TABLE
|
||||
|
||||
|
||||
class BadRequestError(MissingError, PowertoolsBadRequestError): ...
|
||||
@@ -37,12 +38,7 @@ user_collect = DynamoDBCollection(user_layer, exception_cls=BadRequestError)
|
||||
elastic_client = Elasticsearch(**ELASTIC_CONN)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/',
|
||||
compress=True,
|
||||
tags=['User'],
|
||||
summary='Get users',
|
||||
)
|
||||
@router.get('/', compress=True, tags=['User'], summary='Get users')
|
||||
def get_users():
|
||||
event = router.current_event
|
||||
query = event.get_query_string_value('query', '{}')
|
||||
@@ -67,29 +63,28 @@ def post_user(payload: User):
|
||||
return Response(status_code=HTTPStatus.CREATED)
|
||||
|
||||
|
||||
class NewPasswordPayload(BaseModel):
|
||||
class NewPassword(BaseModel):
|
||||
cognito_sub: UUID4
|
||||
new_password: Annotated[str, StringConstraints(min_length=6)]
|
||||
|
||||
|
||||
@router.patch('/<id>', compress=True, tags=['User'])
|
||||
def patch_reset(id: str, payload: NewPasswordPayload):
|
||||
def patch_newpassword(id: str, payload: NewPassword):
|
||||
return Response(status_code=HTTPStatus.OK)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/<id>',
|
||||
compress=True,
|
||||
tags=['User'],
|
||||
summary='Get user',
|
||||
)
|
||||
@router.get('/<id>', compress=True, tags=['User'], summary='Get user')
|
||||
def get_user(id: str):
|
||||
return user_collect.get_item(KeyPair(id, '0'))
|
||||
|
||||
|
||||
@router.get('/<id>/idp', compress=True, include_in_schema=False)
|
||||
def get_idp(id: str):
|
||||
return []
|
||||
return cognito.admin_get_user(
|
||||
sub=id,
|
||||
user_pool_id=USER_POOOL_ID,
|
||||
idp_client=idp_client,
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
@@ -99,7 +94,7 @@ def get_idp(id: str):
|
||||
summary='Get user emails',
|
||||
)
|
||||
def get_emails(id: str):
|
||||
return user_collect.get_items(
|
||||
return user_collect.query(
|
||||
KeyPair(id, PrefixKey('emails')),
|
||||
start_key=router.current_event.get_query_string_value('start_key', None),
|
||||
)
|
||||
@@ -112,7 +107,7 @@ def get_emails(id: str):
|
||||
summary='Get user logs',
|
||||
)
|
||||
def get_logs(id: str):
|
||||
return user_collect.get_items(
|
||||
return user_collect.query(
|
||||
# Post-migration: uncomment to enable PartitionKey with a composite key (id with `logs` prefix).
|
||||
# PartitionKey(ComposeKey(id, prefix='logs')),
|
||||
PartitionKey(ComposeKey(id, prefix='log', delimiter=':')),
|
||||
@@ -127,7 +122,7 @@ def get_logs(id: str):
|
||||
summary='Get user orgs',
|
||||
)
|
||||
def get_orgs(id: str):
|
||||
return user_collect.get_items(
|
||||
return user_collect.query(
|
||||
KeyPair(id, PrefixKey('orgs')),
|
||||
start_key=router.current_event.get_query_string_value('start_key', None),
|
||||
)
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "tags#MqiRQWy9cSBEci93aKBvTd"}, "tag": {"S": "Test"}, "create_date": {"S": "2023-09-22T18:31:11.475449-03:00"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "tags#NQ3YmmTesfoSyHCkPKGKEF"}, "tag": {"S": "F\u00e1brica"}, "create_date": {"S": "2023-09-22T18:31:11.475449-03:00"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "tags#bg45io8igarjsA4BzPQyrz"}, "tag": {"S": "Escrit\u00f3rio"}, "create_date": {"S": "2023-09-22T18:31:11.475449-03:00"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "payment_policy"}, "due_days": {"N": "90"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "billing_policy"}, "billing_day": {"N": "2"}, "payment_method": {"S": "PIX"}}
|
||||
{"sk": {"S": "admin#18606"}, "create_date": {"S": "2023-09-22T18:31:11.475449-03:00"}, "id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "email": {"S": "mateushickmann@petrobras.com.br"}, "name": {"S": "MATEUS LATTIK HICKMANN"}}
|
||||
{"sk": {"S": "admin#21425"}, "create_date": {"S": "2023-09-22T18:34:06.480230-03:00"}, "id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "email": {"S": "sergio@inbep.com.br"}, "name": {"S": "S\u00e9rgio Siqueira"}}
|
||||
{"sk": {"S": "admin#2338"}, "create_date": {"S": "2023-09-22T18:28:10.121068-03:00"}, "id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "email": {"S": "empresa@inbep.com.br"}, "name": {"S": "Empresa Teste"}}
|
||||
@@ -68,3 +70,6 @@
|
||||
{"id": {"S": "webhook_requests#*#0e7f4d2e62ec525fc94465a6dd7299d2"}, "sk": {"S": "2025-03-03T15:47:42.039256-03:00"}, "request": {"M": {"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "headers": {"M": {"Accept": {"S": "*/*"}, "Accept-Encoding": {"S": "gzip, deflate"}, "Connection": {"S": "keep-alive"}, "Content-Length": {"S": "108"}, "Content-Type": {"S": "application/json"}, "User-Agent": {"S": "eduseg/python-requests/2.32.3"}}}, "payload": {"M": {"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "email": {"S": "sergio@somosbeta.com.br"}, "name": {"S": "S\u00e9rgio Rafael de Siqueira"}}}}}, "response": {"M": {"body": {"S": "{\"message\":\"Workflow was started\"}"}, "elapsed_time": {"S": "0.14"}, "headers": {"M": {"alt-svc": {"S": "h3=\":443\"; ma=86400"}, "cf-cache-status": {"S": "DYNAMIC"}, "CF-RAY": {"S": "8fc528b57b62a3f0-GRU"}, "Connection": {"S": "keep-alive"}, "Content-Length": {"S": "34"}, "Content-Type": {"S": "application/json; charset=utf-8"}, "Date": {"S": "Fri, 03 Jan 2025 18:47:44 GMT"}, "etag": {"S": "W/\"22-6OS7cK0FzqnV2NeDHdOSGS1bVUs\""}, "NEL": {"S": "{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}"}, "Report-To": {"S": "{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=FMkgKCTOnFvNgtE30yiYnM4XtK8q99O62s7Ep57KDNc3YGiy3W1j%2BzfS0vqJNylSAn5viU3MMGJvTIwPsYQ6jQ298t1p0hYd1KPwURhxchME4hc%2BsO0NNAv%2FFEpXv1ZYWw%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}"}, "Server": {"S": "cloudflare"}, "server-timing": {"S": "cfL4;desc=\"?proto=TCP&rtt=1016&min_rtt=998&rtt_var=411&sent=4&recv=7&lost=0&retrans=0&sent_bytes=2836&recv_bytes=999&delivery_rate=2522648&cwnd=251&unsent_bytes=0&cid=1b26053952909423&ts=93&x=0\""}, "Strict-Transport-Security": {"S": "max-age=0; includeSubDomains"}, "vary": {"S": "Accept-Encoding"}}}, "status_code": {"S": "200"}}}, "update_date": {"S": "2025-01-03T15:47:44.537597-03:00"}, "url": {"S": "https://n8n.sergio.run/webhook/56bb43b8-533c-4e8b-bdaa-3f7c2b0e548f"}}
|
||||
{"id": {"S": "webhooks#*"}, "sk": {"S": "1e3759c9c4cfa7aaf86ac281bdb8fd6f"}, "author": {"M": {"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "name": {"S": "S\u00e9rgio Rafael de Siqueira"}}}, "create_date": {"S": "2025-01-06T15:00:39.363207-03:00"}, "event_type": {"S": "insert"}, "resource": {"S": "users"}, "url": {"S": "https://hook.us2.make.com/hgkc5oj5dbpfld5qvu1xmsu22ond93l9"}}
|
||||
{"id": {"S": "log:5OxmMjL-ujoR5IMGegQz"},"sk": {"S": "2024-02-26T11:48:17.605911-03:00"},"action": {"S": "OPEN_EMAIL"},"data": {"M": {"ip_address": {"S": "66.249.83.73"},"message_id": {"S": "0103018de5de75cf-670bf01f-7ccf-4ce0-88b4-7c85cd0d06d0-000000"},"recipients": {"L": [{"S": "sergio@somosbeta.com.br"}]},"subject": {"S": "Re: (sem assunto)"},"timestamp": {"S": "2024-02-26T14:48:16.976Z"},"user_agent": {"S": "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)"}}},"ttl": {"N": "1772030897"}}
|
||||
{"id": {"S": "7zf52CWrTS3csRBFWU5rkq"},"sk": {"S": "0"},"cognito:sub": {"S": "58efed8d-d276-41a8-8502-4ab8b5a6415e"},"cpf": {"S": "04330965275"},"createDate": {"S": "2025-04-08T10:24:46.493980-03:00"},"email": {"S": "barbara.gomes@sinobras.com.br"},"email_verified": {"BOOL": true},"konviva:id": {"N": "199205"},"lastLogin": {"S": "2025-04-10T12:01:48.380215-03:00"},"name": {"S": "Barbara Kamyla Vasconcelos Gomes"},"tenant__org_id": {"SS": ["EkvQwpmmL6vzWtJunM5dCJ"]},"update_date": {"S": "2025-04-10T08:50:22.530758-03:00"}}
|
||||
{"id": {"S": "7zf52CWrTS3csRBFWU5rkq"},"sk": {"S": "acls#EkvQwpmmL6vzWtJunM5dCJ"},"create_date": {"S": "2025-04-10T09:36:41.133157-03:00"},"roles": {"L": [{"S": "ADMIN"}]}}
|
||||
{"id": {"S": "7zf52CWrTS3csRBFWU5rkq"},"sk": {"S": "orgs#EkvQwpmmL6vzWtJunM5dCJ"},"cnpj": {"S": "07933914000154"},"create_date": {"S": "2025-04-08T10:24:46.493980-03:00"},"name": {"S": "SIDERURGICA NORTE BRASIL S.A"}}
|
||||
|
||||
@@ -32,3 +32,5 @@ match os.getenv('AWS_SAM_LOCAL'), os.getenv('PYTEST_VERSION'):
|
||||
'cloud_id': ELASTIC_CLOUD_ID,
|
||||
'basic_auth': ('elastic', ELASTIC_AUTH_PASS),
|
||||
}
|
||||
|
||||
USER_POOOL_ID = 'sa-east-1_s6YmVSfXj'
|
||||
|
||||
@@ -23,7 +23,7 @@ Globals:
|
||||
Architectures:
|
||||
- x86_64
|
||||
Layers:
|
||||
- !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:35
|
||||
- !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:42
|
||||
Environment:
|
||||
Variables:
|
||||
TZ: America/Sao_Paulo
|
||||
@@ -82,6 +82,15 @@ Resources:
|
||||
TableName: !Ref CourseTable
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref OrderTable
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref EnrollmentTable
|
||||
- Version: 2012-10-17
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- cognito-idp:AdminGetUser
|
||||
- cognito-idp:AdminSetUserPassword
|
||||
Resource: !Sub arn:aws:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/*
|
||||
Events:
|
||||
Preflight:
|
||||
Type: HttpApi
|
||||
|
||||
@@ -59,7 +59,7 @@ def test_post_course(
|
||||
assert r['statusCode'] == HTTPStatus.CREATED
|
||||
|
||||
collect = DynamoDBCollection(dynamodb_persistence_layer)
|
||||
logs = collect.get_items(
|
||||
logs = collect.query(
|
||||
PartitionKey(
|
||||
ComposeKey('5OxmMjL-ujoR5IMGegQz', prefix='log', delimiter=':'),
|
||||
)
|
||||
|
||||
@@ -8,5 +8,8 @@
|
||||
{"id": {"S": "log:5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "2024-02-08T16:42:33.776409-03:00"}, "action": {"S": "OPEN_EMAIL"}}
|
||||
{"id": {"S": "log:5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "2019-03-25T00:00:00-03:00"}, "action": {"S": "CLICK_EMAIL"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "0"}, "name": {"S": "EDUSEG"}, "cnpj": {"S": "15608435000190"}, "email": {"S": "org+15608435000190@users.noreply.betaeducacao.com.br"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "payment_policies"}, "due_days": {"N": "90"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "payment_policy"}, "due_days": {"N": "90"}}
|
||||
{"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "billing_policy"}, "billing_day": {"N": "1"}, "payment_method": {"S": "PIX"}}
|
||||
{"id": {"S": "90d7f0d2-d9a4-4467-a31c-f9a7955964cf"}, "sk": {"S": "0"}, "access_period": {"N": "720"}, "create_date": {"S": "2024-12-30T00:00:33.088916-03:00"},"konviva__class_id": {"N": "266"},"name": {"S": "Reciclagem em NR-18 Básico"},"tenant__org_id": {"SS": ["cJtK9SsnJhKPyxESe7g3DG"]}}
|
||||
{"id": {"S": "43ea4475-c369-4f90-b576-135b7df5106b"}, "sk": {"S": "0"}, "status": {"S": "PENDING"}}
|
||||
{"id": {"S": "43ea4475-c369-4f90-b576-135b7df5106b"}, "sk": {"S": "cancel_policy"}}
|
||||
|
||||
24
http-api/uv.lock
generated
24
http-api/uv.lock
generated
@@ -521,7 +521,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "layercake"
|
||||
version = "0.1.16"
|
||||
version = "0.2.5"
|
||||
source = { directory = "../layercake" }
|
||||
dependencies = [
|
||||
{ name = "arnparse" },
|
||||
@@ -538,6 +538,7 @@ dependencies = [
|
||||
{ name = "pydantic-extra-types" },
|
||||
{ name = "pytz" },
|
||||
{ name = "requests" },
|
||||
{ name = "uuid-utils" },
|
||||
{ name = "weasyprint" },
|
||||
]
|
||||
|
||||
@@ -557,6 +558,7 @@ requires-dist = [
|
||||
{ name = "pydantic-extra-types", specifier = ">=2.10.3" },
|
||||
{ name = "pytz", specifier = ">=2025.1" },
|
||||
{ name = "requests", specifier = ">=2.32.3" },
|
||||
{ name = "uuid-utils", specifier = ">=0.10.0" },
|
||||
{ name = "weasyprint", specifier = ">=65.0" },
|
||||
]
|
||||
|
||||
@@ -938,6 +940,26 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid-utils"
|
||||
version = "0.10.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/0a/cbdb2eb4845dafeb632d02a18f47b02f87f2ce4f25266f5e3c017976ce89/uuid_utils-0.10.0.tar.gz", hash = "sha256:5db0e1890e8f008657ffe6ded4d9459af724ab114cfe82af1557c87545301539", size = 18828 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/44/54/9d22fa16b19e5d1676eba510f08a9c458d96e2a62ff2c8ebad64251afb18/uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d5a4508feefec62456cd6a41bcdde458d56827d908f226803b886d22a3d5e63", size = 573006 },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/8e/f895c6e52aa603e521fbc13b8626ba5dd99b6e2f5a55aa96ba5b232f4c53/uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dbefc2b9113f9dfe56bdae58301a2b3c53792221410d422826f3d1e3e6555fe7", size = 292543 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/58/cc4834f377a5e97d6e184408ad96d13042308de56643b6e24afe1f6f34df/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc49c33edf87d1ec8112a9b43e4cf55326877716f929c165a2cc307d31c73d5", size = 323340 },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/e3/6aeddf148f6a7dd7759621b000e8c85382ec83f52ae79b60842d1dc3ab6b/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0636b6208f69d5a4e629707ad2a89a04dfa8d1023e1999181f6830646ca048a1", size = 329653 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/00/dd6c2164ace70b7b1671d9129267df331481d7d1e5f9c5e6a564f07953f6/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc06452856b724df9dedfc161c3582199547da54aeb81915ec2ed54f92d19b0", size = 365471 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/e7/0ab8080fcae5462a7b5e555c1cef3d63457baffb97a59b9bc7b005a3ecb1/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:263b2589111c61decdd74a762e8f850c9e4386fb78d2cf7cb4dfc537054cda1b", size = 325844 },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/39/52d94e9ef75b03f44b39ffc6ac3167e93e74ef4d010a93d25589d9f48540/uuid_utils-0.10.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a558db48b7096de6b4d2d2210d82bba8586a6d55f99106b03bb7d01dc5c5bcd6", size = 344389 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/29/4824566f62666238290d99c62a58e4ab2a8b9cf2eccf94cebd9b3359131e/uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:807465067f3c892514230326ac71a79b28a8dfe2c88ecd2d5675fc844f3c76b5", size = 510078 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/8f/bbcc7130d652462c685f0d3bd26bb214b754215b476340885a4cb50fb89a/uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:57423d4a2b9d7b916de6dbd75ba85465a28f9578a89a97f7d3e098d9aa4e5d4a", size = 515937 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/f8/34e0c00f5f188604d336713e6a020fcf53b10998e8ab24735a39ab076740/uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:76d8d660f18ff6b767e319b1b5f927350cd92eafa4831d7ef5b57fdd1d91f974", size = 494111 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/52/b7f0066cc90a7a9c28d54061ed195cd617fde822e5d6ac3ccc88509c3c44/uuid_utils-0.10.0-cp39-abi3-win32.whl", hash = "sha256:6c11a71489338837db0b902b75e1ba7618d5d29f05fde4f68b3f909177dbc226", size = 173520 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/15/f04f58094674d333974243fb45d2c740cf4b79186fb707168e57943c84a3/uuid_utils-0.10.0-cp39-abi3-win_amd64.whl", hash = "sha256:11c55ae64f6c0a7a0c741deae8ca2a4eaa11e9c09dbb7bec2099635696034cf7", size = 182965 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wcwidth"
|
||||
version = "0.2.13"
|
||||
|
||||
Reference in New Issue
Block a user