move cli
This commit is contained in:
@@ -8,9 +8,12 @@ start-api: build
|
|||||||
sam local start-api
|
sam local start-api
|
||||||
|
|
||||||
openapi:
|
openapi:
|
||||||
uv run openapi.py && \
|
uv run -m cli.openapi && \
|
||||||
uv run python -m http.server 80 -d swagger
|
uv run python -m http.server 80 -d swagger
|
||||||
|
|
||||||
|
seeds:
|
||||||
|
uv run -m cli.seeds
|
||||||
|
|
||||||
pytest:
|
pytest:
|
||||||
uv run pytest
|
uv run pytest
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
from aws_lambda_powertools import Logger, Tracer
|
from aws_lambda_powertools import Logger, Tracer
|
||||||
from aws_lambda_powertools.event_handler.api_gateway import (
|
from aws_lambda_powertools.event_handler.api_gateway import (
|
||||||
APIGatewayHttpResolver,
|
APIGatewayHttpResolver,
|
||||||
@@ -9,7 +11,7 @@ from aws_lambda_powertools.logging import correlation_paths
|
|||||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||||
|
|
||||||
from middlewares import AuthorizerMiddleware
|
from middlewares import AuthorizerMiddleware
|
||||||
from routes import courses, enrollments, lookup, orders, me, users, webhooks
|
from routes import courses, enrollments, lookup, me, orders, users, webhooks
|
||||||
|
|
||||||
tracer = Tracer()
|
tracer = Tracer()
|
||||||
logger = Logger(__name__)
|
logger = Logger(__name__)
|
||||||
@@ -38,5 +40,5 @@ def exc_error(exc: ServiceError):
|
|||||||
|
|
||||||
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
|
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP)
|
||||||
@tracer.capture_lambda_handler
|
@tracer.capture_lambda_handler
|
||||||
def lambda_handler(event: dict, context: LambdaContext) -> dict:
|
def lambda_handler(event: dict[str, Any], context: LambdaContext) -> dict[str, Any]:
|
||||||
return app.resolve(event, context)
|
return app.resolve(event, context)
|
||||||
|
|||||||
0
http-api/cli/__init__.py
Normal file
0
http-api/cli/__init__.py
Normal file
@@ -19,7 +19,7 @@ collect = DynamoDBCollection(user_layer)
|
|||||||
LIMIT = 25
|
LIMIT = 25
|
||||||
|
|
||||||
|
|
||||||
@router.get('/')
|
@router.get('/', include_in_schema=False)
|
||||||
def me():
|
def me():
|
||||||
user: AuthenticatedUser = router.context['user']
|
user: AuthenticatedUser = router.context['user']
|
||||||
acls = collect.get_items(
|
acls = collect.get_items(
|
||||||
@@ -37,7 +37,7 @@ def me():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get('/konviva')
|
@router.get('/konviva', include_in_schema=False)
|
||||||
def konviva_():
|
def konviva_():
|
||||||
user: AuthenticatedUser = router.context['user']
|
user: AuthenticatedUser = router.context['user']
|
||||||
token = konviva.token(user.email)
|
token = konviva.token(user.email)
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ KONVIVA_API_URL: str = os.getenv('KONVIVA_API_URL') # type: ignore
|
|||||||
KONVIVA_SECRET_KEY: str = os.getenv('KONVIVA_SECRET_KEY') # type: ignore
|
KONVIVA_SECRET_KEY: str = os.getenv('KONVIVA_SECRET_KEY') # type: ignore
|
||||||
|
|
||||||
|
|
||||||
match (os.getenv('AWS_SAM_LOCAL'), os.getenv('ELASTIC_HOSTS')):
|
match os.getenv('AWS_SAM_LOCAL'), os.getenv('ELASTIC_HOSTS'):
|
||||||
case (str() as AWS_SAM_LOCAL, _) if AWS_SAM_LOCAL:
|
case str() as AWS_SAM_LOCAL, _ if AWS_SAM_LOCAL:
|
||||||
ELASTIC_CONN = {
|
ELASTIC_CONN = {
|
||||||
'hosts': 'http://host.docker.internal:9200',
|
'hosts': 'http://host.docker.internal:9200',
|
||||||
}
|
}
|
||||||
case (_, str() as ELASTIC_HOSTS) if ELASTIC_HOSTS:
|
case _, str() as ELASTIC_HOSTS if ELASTIC_HOSTS:
|
||||||
ELASTIC_CONN = {
|
ELASTIC_CONN = {
|
||||||
'hosts': ELASTIC_HOSTS,
|
'hosts': ELASTIC_HOSTS,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,165 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"/courses/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Course"
|
||||||
|
],
|
||||||
|
"summary": "GET /courses/{id}",
|
||||||
|
"operationId": "get_course_courses__id__get",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Id"
|
||||||
|
},
|
||||||
|
"name": "id",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/enrollments/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Enrollment"
|
||||||
|
],
|
||||||
|
"summary": "GET /enrollments/{id}",
|
||||||
|
"operationId": "get_enrollment_enrollments__id__get",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Id"
|
||||||
|
},
|
||||||
|
"name": "id",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"tags": [
|
||||||
|
"Enrollment"
|
||||||
|
],
|
||||||
|
"summary": "PATCH /enrollments/{id}",
|
||||||
|
"operationId": "cancel_enrollments__id__patch",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Id"
|
||||||
|
},
|
||||||
|
"name": "id",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CancelPayload"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/users/{id}": {
|
"/users/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"User"
|
||||||
|
],
|
||||||
|
"summary": "Get user",
|
||||||
|
"operationId": "get_user_users__id__get",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Id"
|
||||||
|
},
|
||||||
|
"name": "id",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"patch": {
|
"patch": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"User"
|
"User"
|
||||||
@@ -204,135 +362,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/enrollments/{id}": {
|
"/courses": {
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"Enrollment"
|
|
||||||
],
|
|
||||||
"summary": "GET /enrollments/{id}",
|
|
||||||
"operationId": "get_enrollment_enrollments__id__get",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string",
|
|
||||||
"title": "Id"
|
|
||||||
},
|
|
||||||
"name": "id",
|
|
||||||
"in": "path"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"422": {
|
|
||||||
"description": "Validation Error",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/HTTPValidationError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"200": {
|
|
||||||
"description": "Successful Response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"patch": {
|
|
||||||
"tags": [
|
|
||||||
"Enrollment"
|
|
||||||
],
|
|
||||||
"summary": "PATCH /enrollments/{id}",
|
|
||||||
"operationId": "cancel_enrollments__id__patch",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string",
|
|
||||||
"title": "Id"
|
|
||||||
},
|
|
||||||
"name": "id",
|
|
||||||
"in": "path"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"requestBody": {
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/CancelPayload"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"responses": {
|
|
||||||
"422": {
|
|
||||||
"description": "Validation Error",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/HTTPValidationError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"200": {
|
|
||||||
"description": "Successful Response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/courses/{id}": {
|
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"Course"
|
"Course"
|
||||||
],
|
],
|
||||||
"summary": "GET /courses/{id}",
|
"summary": "Get courses",
|
||||||
"operationId": "get_course_courses__id__get",
|
"operationId": "get_courses_courses_get",
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string",
|
|
||||||
"title": "Id"
|
|
||||||
},
|
|
||||||
"name": "id",
|
|
||||||
"in": "path"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"422": {
|
|
||||||
"description": "Validation Error",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/HTTPValidationError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"200": {
|
|
||||||
"description": "Successful Response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/users": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"User"
|
|
||||||
],
|
|
||||||
"summary": "Get users",
|
|
||||||
"operationId": "get_users_users_get",
|
|
||||||
"responses": {
|
"responses": {
|
||||||
"422": {
|
"422": {
|
||||||
"description": "Validation Error",
|
"description": "Validation Error",
|
||||||
@@ -354,16 +390,15 @@
|
|||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"User"
|
"Course"
|
||||||
],
|
],
|
||||||
"summary": "POST /users",
|
"summary": "POST /courses",
|
||||||
"description": "Create user",
|
"operationId": "post_course_courses_post",
|
||||||
"operationId": "post_user_users_post",
|
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/User"
|
"$ref": "#/components/schemas/CoursePayload"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -468,13 +503,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/courses": {
|
"/users": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"Course"
|
"User"
|
||||||
],
|
],
|
||||||
"summary": "GET /courses",
|
"summary": "Get users",
|
||||||
"operationId": "get_courses_courses_get",
|
"operationId": "get_users_users_get",
|
||||||
"responses": {
|
"responses": {
|
||||||
"422": {
|
"422": {
|
||||||
"description": "Validation Error",
|
"description": "Validation Error",
|
||||||
@@ -496,15 +531,15 @@
|
|||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"Course"
|
"User"
|
||||||
],
|
],
|
||||||
"summary": "POST /courses",
|
"summary": "Create user",
|
||||||
"operationId": "post_course_courses_post",
|
"operationId": "post_user_users_post",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/CoursePayload"
|
"$ref": "#/components/schemas/User"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Globals:
|
|||||||
Architectures:
|
Architectures:
|
||||||
- x86_64
|
- x86_64
|
||||||
Layers:
|
Layers:
|
||||||
- !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:21
|
- !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:22
|
||||||
Environment:
|
Environment:
|
||||||
Variables:
|
Variables:
|
||||||
TZ: America/Sao_Paulo
|
TZ: America/Sao_Paulo
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{"id": {"S": "apikey"}, "sk": {"S": "32504457-f133-4c00-936b-6aa712ca9f40"}, "tenant": {"M": {"id": {"S": "*"}, "name": {"S": "default"}}}}
|
{"id": {"S": "apikey"}, "sk": {"S": "MzI1MDQ0NTctZjEzMy00YzAwLTkzNmItNmFhNzEyY2E5ZjQw"}, "tenant": {"M": {"id": {"S": "*"}, "name": {"S": "default"}}}}
|
||||||
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "0"}, "update_date": {"S": "2024-02-08T16:42:33.776409-03:00"}, "create_date": {"S": "2019-03-25T00:00:00-03:00"}, "email_verified": {"BOOL": true}, "cognito:sub": {"S": "58efed8d-d276-41a8-8502-4ab8b5a6415e"}, "cpf": {"S": "07879819908"}, "email": {"S": "sergio@somosbeta.com.br"}, "name": {"S": "S\u00e9rgio Rafael de Siqueira"}, "last_login": {"S": "2024-02-08T20:53:45.818126-03:00"}, "tenant:org_id": {"L": [{"S": "cJtK9SsnJhKPyxESe7g3DG"}]}}
|
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "0"}, "update_date": {"S": "2024-02-08T16:42:33.776409-03:00"}, "create_date": {"S": "2019-03-25T00:00:00-03:00"}, "email_verified": {"BOOL": true}, "cognito:sub": {"S": "58efed8d-d276-41a8-8502-4ab8b5a6415e"}, "cpf": {"S": "07879819908"}, "email": {"S": "sergio@somosbeta.com.br"}, "name": {"S": "S\u00e9rgio Rafael de Siqueira"}, "last_login": {"S": "2024-02-08T20:53:45.818126-03:00"}, "tenant:org_id": {"L": [{"S": "cJtK9SsnJhKPyxESe7g3DG"}]}}
|
||||||
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "cognito"}, "create_date": {"S": "2025-03-03T17:12:26.443507-03:00"}, "sub": {"S": "58efed8d-d276-41a8-8502-4ab8b5a6415e"}}
|
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "cognito"}, "create_date": {"S": "2025-03-03T17:12:26.443507-03:00"}, "sub": {"S": "58efed8d-d276-41a8-8502-4ab8b5a6415e"}}
|
||||||
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "emails#sergio@somosbeta.com.br"}, "email_verified": {"BOOL": true}, "update_date": {"S": "2024-02-08T16:42:33.776409-03:00"}, "create_date": {"S": "2019-03-25T00:00:00-03:00"}, "email_primary": {"BOOL": true}, "mx_record_exists": {"BOOL": true}, "update_date": {"S": "2023-11-09T12:13:04.308986-03:00"}}
|
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "emails#sergio@somosbeta.com.br"}, "email_verified": {"BOOL": true}, "update_date": {"S": "2024-02-08T16:42:33.776409-03:00"}, "create_date": {"S": "2019-03-25T00:00:00-03:00"}, "email_primary": {"BOOL": true}, "mx_record_exists": {"BOOL": true}, "update_date": {"S": "2023-11-09T12:13:04.308986-03:00"}}
|
||||||
|
|||||||
@@ -40,18 +40,27 @@ def test_bearer_apikey(
|
|||||||
|
|
||||||
event = {
|
event = {
|
||||||
'headers': {
|
'headers': {
|
||||||
'authorization': 'Bearer sk-32504457-f133-4c00-936b-6aa712ca9f40',
|
'authorization': 'Bearer sk-MzI1MDQ0NTctZjEzMy00YzAwLTkzNmItNmFhNzEyY2E5ZjQw',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# This data was added from seeds
|
# This data was added from seeds
|
||||||
assert app.lambda_handler(event, lambda_context) == {
|
assert app.lambda_handler(event, lambda_context) == {
|
||||||
'isAuthorized': True,
|
'isAuthorized': True,
|
||||||
'context': {'tenant': {'name': 'default', 'id': '*'}},
|
'context': {
|
||||||
|
'tenant': {
|
||||||
|
'name': 'default',
|
||||||
|
'id': '*',
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# This data was added from seeds
|
# This data was added from seeds
|
||||||
assert app.lambda_handler(
|
assert app.lambda_handler(
|
||||||
{'headers': {'authorization': 'Bearer sk-abc'}},
|
{
|
||||||
|
'headers': {
|
||||||
|
'authorization': 'Bearer sk-abc',
|
||||||
|
}
|
||||||
|
},
|
||||||
lambda_context,
|
lambda_context,
|
||||||
) == {'isAuthorized': False}
|
) == {'isAuthorized': False}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user