From 76c2656dd1a6ecbf94f28e06a9d4234527f0aae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Rafael=20Siqueira?= Date: Thu, 27 Mar 2025 11:54:19 -0300 Subject: [PATCH] move cli --- http-api/Makefile | 5 +- http-api/app.py | 6 +- http-api/cli/__init__.py | 0 http-api/{ => cli}/openapi.py | 0 http-api/{cli.py => cli/seeds.py} | 0 http-api/{ => cli}/seeds/test-courses.jsonl | 0 .../{ => cli}/seeds/test-enrollments.jsonl | 0 http-api/{ => cli}/seeds/test-orders.jsonl | 0 http-api/{ => cli}/seeds/test-users.jsonl | 0 http-api/routes/me/__init__.py | 4 +- http-api/settings.py | 6 +- http-api/swagger/index.html | 311 ++++++++++-------- http-api/template.yaml | 2 +- http-api/tests/seeds.jsonl | 2 +- http-api/tests/test_auth.py | 15 +- 15 files changed, 200 insertions(+), 151 deletions(-) create mode 100644 http-api/cli/__init__.py rename http-api/{ => cli}/openapi.py (100%) rename http-api/{cli.py => cli/seeds.py} (100%) rename http-api/{ => cli}/seeds/test-courses.jsonl (100%) rename http-api/{ => cli}/seeds/test-enrollments.jsonl (100%) rename http-api/{ => cli}/seeds/test-orders.jsonl (100%) rename http-api/{ => cli}/seeds/test-users.jsonl (100%) diff --git a/http-api/Makefile b/http-api/Makefile index bc9d9bc..21871ea 100644 --- a/http-api/Makefile +++ b/http-api/Makefile @@ -8,9 +8,12 @@ start-api: build sam local start-api openapi: - uv run openapi.py && \ + uv run -m cli.openapi && \ uv run python -m http.server 80 -d swagger +seeds: + uv run -m cli.seeds + pytest: uv run pytest diff --git a/http-api/app.py b/http-api/app.py index f4ac2dd..c684545 100644 --- a/http-api/app.py +++ b/http-api/app.py @@ -1,3 +1,5 @@ +from typing import Any + from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler.api_gateway import ( APIGatewayHttpResolver, @@ -9,7 +11,7 @@ from aws_lambda_powertools.logging import correlation_paths from aws_lambda_powertools.utilities.typing import LambdaContext 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() logger = Logger(__name__) @@ -38,5 +40,5 @@ def exc_error(exc: ServiceError): @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP) @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) diff --git a/http-api/cli/__init__.py b/http-api/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/http-api/openapi.py b/http-api/cli/openapi.py similarity index 100% rename from http-api/openapi.py rename to http-api/cli/openapi.py diff --git a/http-api/cli.py b/http-api/cli/seeds.py similarity index 100% rename from http-api/cli.py rename to http-api/cli/seeds.py diff --git a/http-api/seeds/test-courses.jsonl b/http-api/cli/seeds/test-courses.jsonl similarity index 100% rename from http-api/seeds/test-courses.jsonl rename to http-api/cli/seeds/test-courses.jsonl diff --git a/http-api/seeds/test-enrollments.jsonl b/http-api/cli/seeds/test-enrollments.jsonl similarity index 100% rename from http-api/seeds/test-enrollments.jsonl rename to http-api/cli/seeds/test-enrollments.jsonl diff --git a/http-api/seeds/test-orders.jsonl b/http-api/cli/seeds/test-orders.jsonl similarity index 100% rename from http-api/seeds/test-orders.jsonl rename to http-api/cli/seeds/test-orders.jsonl diff --git a/http-api/seeds/test-users.jsonl b/http-api/cli/seeds/test-users.jsonl similarity index 100% rename from http-api/seeds/test-users.jsonl rename to http-api/cli/seeds/test-users.jsonl diff --git a/http-api/routes/me/__init__.py b/http-api/routes/me/__init__.py index 0dad297..c5461df 100644 --- a/http-api/routes/me/__init__.py +++ b/http-api/routes/me/__init__.py @@ -19,7 +19,7 @@ collect = DynamoDBCollection(user_layer) LIMIT = 25 -@router.get('/') +@router.get('/', include_in_schema=False) def me(): user: AuthenticatedUser = router.context['user'] acls = collect.get_items( @@ -37,7 +37,7 @@ def me(): } -@router.get('/konviva') +@router.get('/konviva', include_in_schema=False) def konviva_(): user: AuthenticatedUser = router.context['user'] token = konviva.token(user.email) diff --git a/http-api/settings.py b/http-api/settings.py index b07a6ba..16e5e73 100644 --- a/http-api/settings.py +++ b/http-api/settings.py @@ -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 -match (os.getenv('AWS_SAM_LOCAL'), os.getenv('ELASTIC_HOSTS')): - case (str() as AWS_SAM_LOCAL, _) if AWS_SAM_LOCAL: +match os.getenv('AWS_SAM_LOCAL'), os.getenv('ELASTIC_HOSTS'): + case str() as AWS_SAM_LOCAL, _ if AWS_SAM_LOCAL: ELASTIC_CONN = { 'hosts': 'http://host.docker.internal:9200', } - case (_, str() as ELASTIC_HOSTS) if ELASTIC_HOSTS: + case _, str() as ELASTIC_HOSTS if ELASTIC_HOSTS: ELASTIC_CONN = { 'hosts': ELASTIC_HOSTS, } diff --git a/http-api/swagger/index.html b/http-api/swagger/index.html index daa2560..d5359e4 100644 --- a/http-api/swagger/index.html +++ b/http-api/swagger/index.html @@ -42,7 +42,165 @@ } ], "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}": { + "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": { "tags": [ "User" @@ -204,135 +362,13 @@ } } }, - "/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": {} - } - } - } - } - }, - "/courses/{id}": { + "/courses": { "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": {} - } - } - } - } - }, - "/users": { - "get": { - "tags": [ - "User" - ], - "summary": "Get users", - "operationId": "get_users_users_get", + "summary": "Get courses", + "operationId": "get_courses_courses_get", "responses": { "422": { "description": "Validation Error", @@ -354,16 +390,15 @@ }, "post": { "tags": [ - "User" + "Course" ], - "summary": "POST /users", - "description": "Create user", - "operationId": "post_user_users_post", + "summary": "POST /courses", + "operationId": "post_course_courses_post", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/User" + "$ref": "#/components/schemas/CoursePayload" } } }, @@ -468,13 +503,13 @@ } } }, - "/courses": { + "/users": { "get": { "tags": [ - "Course" + "User" ], - "summary": "GET /courses", - "operationId": "get_courses_courses_get", + "summary": "Get users", + "operationId": "get_users_users_get", "responses": { "422": { "description": "Validation Error", @@ -496,15 +531,15 @@ }, "post": { "tags": [ - "Course" + "User" ], - "summary": "POST /courses", - "operationId": "post_course_courses_post", + "summary": "Create user", + "operationId": "post_user_users_post", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CoursePayload" + "$ref": "#/components/schemas/User" } } }, diff --git a/http-api/template.yaml b/http-api/template.yaml index b0deb98..d3b48b8 100644 --- a/http-api/template.yaml +++ b/http-api/template.yaml @@ -23,7 +23,7 @@ Globals: Architectures: - x86_64 Layers: - - !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:21 + - !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:22 Environment: Variables: TZ: America/Sao_Paulo diff --git a/http-api/tests/seeds.jsonl b/http-api/tests/seeds.jsonl index 34038e9..ac7cec3 100644 --- a/http-api/tests/seeds.jsonl +++ b/http-api/tests/seeds.jsonl @@ -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": "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"}} diff --git a/http-api/tests/test_auth.py b/http-api/tests/test_auth.py index 1fa81d4..c60370b 100644 --- a/http-api/tests/test_auth.py +++ b/http-api/tests/test_auth.py @@ -40,18 +40,27 @@ def test_bearer_apikey( event = { 'headers': { - 'authorization': 'Bearer sk-32504457-f133-4c00-936b-6aa712ca9f40', + 'authorization': 'Bearer sk-MzI1MDQ0NTctZjEzMy00YzAwLTkzNmItNmFhNzEyY2E5ZjQw', } } # This data was added from seeds assert app.lambda_handler(event, lambda_context) == { 'isAuthorized': True, - 'context': {'tenant': {'name': 'default', 'id': '*'}}, + 'context': { + 'tenant': { + 'name': 'default', + 'id': '*', + } + }, } # This data was added from seeds assert app.lambda_handler( - {'headers': {'authorization': 'Bearer sk-abc'}}, + { + 'headers': { + 'authorization': 'Bearer sk-abc', + } + }, lambda_context, ) == {'isAuthorized': False}