├── src ├── __init__.py ├── data │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ ├── __init__.cpython-38.pyc │ │ ├── event_handler.cpython-310.pyc │ │ ├── event_handler.cpython-38.pyc │ │ ├── check_in_handler.cpython-38.pyc │ │ └── attendees_handler.cpython-38.pyc │ ├── check_in_handler.py │ ├── event_handler.py │ └── attendees_handler.py ├── errors │ ├── __init__.py │ ├── error_types │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── http_conflict.cpython-38.pyc │ │ │ └── http_not_found.cpython-38.pyc │ │ ├── http_conflict.py │ │ └── http_not_found.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ └── error_handler.cpython-38.pyc │ └── error_handler.py ├── main │ ├── __init__.py │ ├── routes │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-310.pyc │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── event_routes.cpython-38.pyc │ │ │ ├── event_routes.cpython-310.pyc │ │ │ ├── attendees_routes.cpython-38.pyc │ │ │ └── check_in_routes.cpython-38.pyc │ │ ├── check_in_routes.py │ │ ├── event_routes.py │ │ └── attendees_routes.py │ ├── server │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── server.cpython-310.pyc │ │ │ ├── server.cpython-38.pyc │ │ │ ├── __init__.cpython-310.pyc │ │ │ └── __init__.cpython-38.pyc │ │ └── server.py │ └── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── __init__.cpython-38.pyc ├── models │ ├── __init__.py │ ├── repository │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── __init__.cpython-310.pyc │ │ │ ├── events_repository.cpython-310.pyc │ │ │ ├── events_repository.cpython-38.pyc │ │ │ ├── attendees_repository.cpython-310.pyc │ │ │ ├── attendees_repository.cpython-38.pyc │ │ │ ├── check_ins_repository.cpython-38.pyc │ │ │ ├── events_repository_test.cpython-310-pytest-8.1.1.pyc │ │ │ ├── events_repository_test.cpython-38-pytest-8.1.1.pyc │ │ │ ├── attendees_repository_test.cpython-38-pytest-8.1.1.pyc │ │ │ └── attendees_repository_test.cpython-310-pytest-8.1.1.pyc │ │ ├── events_repository_test.py │ │ ├── check_ins_repository.py │ │ ├── attendees_repository_test.py │ │ ├── events_repository.py │ │ └── attendees_repository.py │ ├── settings │ │ ├── __init__.py │ │ ├── base.py │ │ ├── __pycache__ │ │ │ ├── base.cpython-310.pyc │ │ │ ├── base.cpython-38.pyc │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── __init__.cpython-310.pyc │ │ │ ├── connection.cpython-38.pyc │ │ │ └── connection.cpython-310.pyc │ │ └── connection.py │ ├── entities │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── events.cpython-310.pyc │ │ │ ├── events.cpython-38.pyc │ │ │ ├── __init__.cpython-310.pyc │ │ │ ├── attendees.cpython-310.pyc │ │ │ ├── attendees.cpython-38.pyc │ │ │ └── check_ins.cpython-38.pyc │ │ ├── check_ins.py │ │ ├── events.py │ │ └── attendees.py │ └── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── __init__.cpython-38.pyc ├── http_types │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── __init__.cpython-310.pyc │ │ ├── http_request.cpython-310.pyc │ │ ├── http_request.cpython-38.pyc │ │ ├── http_response.cpython-38.pyc │ │ └── http_response.cpython-310.pyc │ ├── http_request.py │ └── http_response.py └── __pycache__ │ ├── __init__.cpython-310.pyc │ └── __init__.cpython-38.pyc ├── storage.db ├── app.py ├── case.py ├── requirements.txt └── init └── schema.sql /src/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/data/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/errors/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/http_types/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/routes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/server/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/models/repository/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/models/settings/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/errors/error_types/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/models/entities/__init__.py: -------------------------------------------------------------------------------- 1 | from .events import Events -------------------------------------------------------------------------------- /storage.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/storage.db -------------------------------------------------------------------------------- /src/models/settings/base.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy.ext.declarative import declarative_base 2 | 3 | Base = declarative_base() 4 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from src.main.server.server import app 2 | 3 | if __name__ == "__main__": 4 | app.run(host="0.0.0.0", port=3000, debug=True) 5 | -------------------------------------------------------------------------------- /src/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/data/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/data/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/data/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/data/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/main/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/main/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/errors/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/errors/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/data/__pycache__/event_handler.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/data/__pycache__/event_handler.cpython-310.pyc -------------------------------------------------------------------------------- /src/data/__pycache__/event_handler.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/data/__pycache__/event_handler.cpython-38.pyc -------------------------------------------------------------------------------- /src/http_types/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/http_types/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/main/server/__pycache__/server.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/server/__pycache__/server.cpython-310.pyc -------------------------------------------------------------------------------- /src/main/server/__pycache__/server.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/server/__pycache__/server.cpython-38.pyc -------------------------------------------------------------------------------- /src/data/__pycache__/check_in_handler.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/data/__pycache__/check_in_handler.cpython-38.pyc -------------------------------------------------------------------------------- /src/errors/__pycache__/error_handler.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/errors/__pycache__/error_handler.cpython-38.pyc -------------------------------------------------------------------------------- /src/http_types/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/http_types/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/main/routes/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/routes/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/main/routes/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/routes/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/main/server/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/server/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/main/server/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/server/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/settings/__pycache__/base.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/settings/__pycache__/base.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/settings/__pycache__/base.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/settings/__pycache__/base.cpython-38.pyc -------------------------------------------------------------------------------- /src/data/__pycache__/attendees_handler.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/data/__pycache__/attendees_handler.cpython-38.pyc -------------------------------------------------------------------------------- /src/http_types/__pycache__/http_request.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/http_types/__pycache__/http_request.cpython-310.pyc -------------------------------------------------------------------------------- /src/http_types/__pycache__/http_request.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/http_types/__pycache__/http_request.cpython-38.pyc -------------------------------------------------------------------------------- /src/http_types/__pycache__/http_response.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/http_types/__pycache__/http_response.cpython-38.pyc -------------------------------------------------------------------------------- /src/main/routes/__pycache__/event_routes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/routes/__pycache__/event_routes.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/events.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/events.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/events.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/events.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/settings/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/settings/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/http_types/__pycache__/http_response.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/http_types/__pycache__/http_response.cpython-310.pyc -------------------------------------------------------------------------------- /src/main/routes/__pycache__/event_routes.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/routes/__pycache__/event_routes.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/attendees.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/attendees.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/attendees.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/attendees.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/entities/__pycache__/check_ins.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/entities/__pycache__/check_ins.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/settings/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/settings/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/settings/__pycache__/connection.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/settings/__pycache__/connection.cpython-38.pyc -------------------------------------------------------------------------------- /src/errors/error_types/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/errors/error_types/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /src/main/routes/__pycache__/attendees_routes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/routes/__pycache__/attendees_routes.cpython-38.pyc -------------------------------------------------------------------------------- /src/main/routes/__pycache__/check_in_routes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/main/routes/__pycache__/check_in_routes.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/settings/__pycache__/connection.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/settings/__pycache__/connection.cpython-310.pyc -------------------------------------------------------------------------------- /src/errors/error_types/__pycache__/http_conflict.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/errors/error_types/__pycache__/http_conflict.cpython-38.pyc -------------------------------------------------------------------------------- /src/errors/error_types/__pycache__/http_not_found.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/errors/error_types/__pycache__/http_not_found.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/events_repository.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/events_repository.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/events_repository.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/events_repository.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/attendees_repository.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/attendees_repository.cpython-310.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/attendees_repository.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/attendees_repository.cpython-38.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/check_ins_repository.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/check_ins_repository.cpython-38.pyc -------------------------------------------------------------------------------- /src/http_types/http_request.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | 3 | class HttpRequest: 4 | def __init__(self, body: Dict = None, param: Dict = None) -> None: 5 | self.body = body 6 | self.param = param 7 | -------------------------------------------------------------------------------- /src/http_types/http_response.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | 3 | class HttpResponse: 4 | def __init__(self, body: Dict, status_code: int) -> None: 5 | self.body = body 6 | self.status_code = status_code 7 | -------------------------------------------------------------------------------- /src/models/repository/__pycache__/events_repository_test.cpython-310-pytest-8.1.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/events_repository_test.cpython-310-pytest-8.1.1.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/events_repository_test.cpython-38-pytest-8.1.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/events_repository_test.cpython-38-pytest-8.1.1.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/attendees_repository_test.cpython-38-pytest-8.1.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/attendees_repository_test.cpython-38-pytest-8.1.1.pyc -------------------------------------------------------------------------------- /src/models/repository/__pycache__/attendees_repository_test.cpython-310-pytest-8.1.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rocketseat-education/nlw-unite-python/HEAD/src/models/repository/__pycache__/attendees_repository_test.cpython-310-pytest-8.1.1.pyc -------------------------------------------------------------------------------- /case.py: -------------------------------------------------------------------------------- 1 | class AlgumaCoisa: 2 | def __enter__(self): 3 | print('Estou Entrando') 4 | 5 | def __exit__(self, exc_type, exc_val, exc_tb): 6 | print('Estou saindo') 7 | 8 | 9 | with AlgumaCoisa() as ola: 10 | print('Estou no meio') 11 | -------------------------------------------------------------------------------- /src/errors/error_types/http_conflict.py: -------------------------------------------------------------------------------- 1 | class HttpConflictError(Exception): 2 | def __init__(self, message: str) -> None: 3 | super().__init__(message) 4 | self.message = message 5 | self.name = "Conflict" 6 | self.status_code = 409 7 | -------------------------------------------------------------------------------- /src/errors/error_types/http_not_found.py: -------------------------------------------------------------------------------- 1 | class HttpNotFoundError(Exception): 2 | def __init__(self, message: str) -> None: 3 | super().__init__(message) 4 | self.message = message 5 | self.name = "Not Found" 6 | self.status_code = 404 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | blinker==1.7.0 2 | click==8.1.7 3 | exceptiongroup==1.2.0 4 | flask==3.0.2 5 | Flask-Cors==4.0.0 6 | greenlet==3.0.3 7 | importlib-metadata==7.1.0 8 | iniconfig==2.0.0 9 | itsdangerous==2.1.2 10 | Jinja2==3.1.3 11 | MarkupSafe==2.1.5 12 | packaging==24.0 13 | pluggy==1.4.0 14 | pytest==8.1.1 15 | SQLAlchemy==2.0.28 16 | tomli==2.0.1 17 | typing-extensions==4.10.0 18 | werkzeug==3.0.1 19 | zipp==3.18.1 20 | -------------------------------------------------------------------------------- /src/models/entities/check_ins.py: -------------------------------------------------------------------------------- 1 | from src.models.settings.base import Base 2 | from sqlalchemy import Column, String, Integer, DateTime, ForeignKey 3 | from sqlalchemy.sql import func 4 | 5 | class CheckIns(Base): 6 | __tablename__ = "check_ins" 7 | 8 | id = Column(Integer, primary_key=True) 9 | created_at = Column(DateTime, default=func.now()) 10 | attendeeId = Column(String, ForeignKey("attendees.id")) 11 | 12 | def __repr__(self): 13 | return f"CheckIns [attendeeId={self.attendeeId}]" 14 | -------------------------------------------------------------------------------- /src/models/entities/events.py: -------------------------------------------------------------------------------- 1 | from src.models.settings.base import Base 2 | from sqlalchemy import Column, String, Integer 3 | 4 | class Events(Base): 5 | __tablename__ = "events" 6 | 7 | id = Column(String, primary_key=True) 8 | title = Column(String, nullable=False) 9 | details = Column(String) 10 | slug = Column(String, nullable=False) 11 | maximum_attendees = Column(Integer) 12 | 13 | def __repr__(self): 14 | return f"Events [title={self.title}, maximum_attendees={self.maximum_attendees}]" 15 | -------------------------------------------------------------------------------- /src/main/server/server.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask_cors import CORS 3 | from src.models.settings.connection import db_connection_handler 4 | 5 | db_connection_handler.connect_to_db() 6 | 7 | app = Flask(__name__) 8 | CORS(app) 9 | 10 | from src.main.routes.event_routes import event_route_bp 11 | from src.main.routes.attendees_routes import attendees_route_bp 12 | from src.main.routes.check_in_routes import check_in_route_bp 13 | 14 | app.register_blueprint(event_route_bp) 15 | app.register_blueprint(attendees_route_bp) 16 | app.register_blueprint(check_in_route_bp) 17 | -------------------------------------------------------------------------------- /src/models/entities/attendees.py: -------------------------------------------------------------------------------- 1 | from src.models.settings.base import Base 2 | from sqlalchemy import Column, String, DateTime, ForeignKey 3 | from sqlalchemy.sql import func 4 | 5 | class Attendees(Base): 6 | __tablename__ = "attendees" 7 | 8 | id = Column(String, primary_key=True) 9 | name = Column(String, nullable=False) 10 | email = Column(String, nullable=False) 11 | event_id = Column(String, ForeignKey("events.id")) 12 | created_at = Column(DateTime, default=func.now()) 13 | 14 | def __repr__(self): 15 | return f"Attendees [name={self.name}, email={self.email}, event_id={self.event_id}]" 16 | -------------------------------------------------------------------------------- /src/data/check_in_handler.py: -------------------------------------------------------------------------------- 1 | from src.models.repository.check_ins_repository import CheckInRepository 2 | from src.http_types.http_request import HttpRequest 3 | from src.http_types.http_response import HttpResponse 4 | 5 | class CheckInHandler: 6 | def __init__(self) -> None: 7 | self.__check_in_respository = CheckInRepository() 8 | 9 | def registry(self, http_request: HttpRequest) -> HttpResponse: 10 | check_in_infos = http_request.param["attendee_id"] 11 | self.__check_in_respository.insert_check_in(check_in_infos) 12 | 13 | return HttpResponse( 14 | body=None, 15 | status_code=201 16 | ) 17 | -------------------------------------------------------------------------------- /src/errors/error_handler.py: -------------------------------------------------------------------------------- 1 | from src.http_types.http_response import HttpResponse 2 | from .error_types.http_conflict import HttpConflictError 3 | from .error_types.http_not_found import HttpNotFoundError 4 | 5 | def handle_error(error: Exception) -> HttpResponse: 6 | if isinstance(error, (HttpConflictError, HttpNotFoundError)): 7 | return HttpResponse( 8 | body={ 9 | "errors": [{ 10 | "title": error.name, 11 | "details": error.message 12 | }] 13 | }, 14 | status_code=error.status_code 15 | ) 16 | 17 | return HttpResponse( 18 | body={ 19 | "errors": [{ 20 | "title": "error", 21 | "details": str(error) 22 | }] 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /src/models/settings/connection.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import create_engine 2 | from sqlalchemy.orm import sessionmaker 3 | 4 | class __DBConnectionHandler: 5 | def __init__(self) -> None: 6 | self.__connection_string = "{}:///{}".format( 7 | "sqlite", 8 | "storage.db" 9 | ) 10 | self.__engine = None 11 | self.session = None 12 | 13 | def connect_to_db(self) -> None: 14 | self.__engine = create_engine(self.__connection_string) 15 | 16 | def get_engine(self): 17 | return self.__engine 18 | 19 | def __enter__(self): 20 | session_maker = sessionmaker() 21 | self.session = session_maker(bind=self.__engine) 22 | return self 23 | 24 | def __exit__(self, exc_type, exc_val, exc_tb): 25 | self.session.close() 26 | 27 | db_connection_handler = __DBConnectionHandler() 28 | -------------------------------------------------------------------------------- /src/main/routes/check_in_routes.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, jsonify, request 2 | from src.http_types.http_request import HttpRequest 3 | from src.data.check_in_handler import CheckInHandler 4 | from src.errors.error_handler import handle_error 5 | 6 | check_in_route_bp = Blueprint("check_in_route", __name__) 7 | 8 | @check_in_route_bp.route("/attendees//check-in", methods=["POST"]) 9 | def create_check_in(attendee_id): 10 | try: 11 | check_in_handler = CheckInHandler() 12 | http_request = HttpRequest(param={ "attendee_id": attendee_id }) 13 | http_response = check_in_handler.registry(http_request) 14 | 15 | return jsonify(http_response.body), http_response.status_code 16 | except Exception as exception: 17 | http_response = handle_error(exception) 18 | return jsonify(http_response.body), http_response.status_code 19 | -------------------------------------------------------------------------------- /src/models/repository/events_repository_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from src.models.settings.connection import db_connection_handler 3 | from .events_repository import EventsRepository 4 | 5 | db_connection_handler.connect_to_db() 6 | 7 | @pytest.mark.skip(reason="Novo registro em banco de dados") 8 | def test_insert_event(): 9 | event = { 10 | "uuid": "meu-uuid-e-nois2", 11 | "title": "meu title", 12 | "slug": "meu-slug-aqui!2", 13 | "maximum_attendees": 20 14 | } 15 | 16 | events_repository = EventsRepository() 17 | response = events_repository.insert_event(event) 18 | print(response) 19 | 20 | @pytest.mark.skip(reason="Nao necessita") 21 | def test_get_event_by_id(): 22 | event_id = "meu-uuid-e-nois2" 23 | events_repository = EventsRepository() 24 | response = events_repository.get_event_by_id(event_id) 25 | print(response) 26 | print(response.title) 27 | -------------------------------------------------------------------------------- /src/models/repository/check_ins_repository.py: -------------------------------------------------------------------------------- 1 | from src.models.settings.connection import db_connection_handler 2 | from src.models.entities.check_ins import CheckIns 3 | from sqlalchemy.exc import IntegrityError 4 | from src.errors.error_types.http_conflict import HttpConflictError 5 | 6 | class CheckInRepository: 7 | def insert_check_in(self, attendee_id: str) -> str: 8 | with db_connection_handler as database: 9 | try: 10 | check_in = ( 11 | CheckIns(attendeeId=attendee_id) 12 | ) 13 | database.session.add(check_in) 14 | database.session.commit() 15 | return attendee_id 16 | except IntegrityError: 17 | raise HttpConflictError('Check In ja cadastrado!') 18 | except Exception as exception: 19 | database.session.rollback() 20 | raise exception 21 | -------------------------------------------------------------------------------- /src/models/repository/attendees_repository_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from .attendees_repository import AttendeesRepository 3 | from src.models.settings.connection import db_connection_handler 4 | 5 | db_connection_handler.connect_to_db() 6 | 7 | @pytest.mark.skip(reason="Novo registro em banco de dados") 8 | def test_insert_attendee(): 9 | event_id = "meu-uuid-e-nois" 10 | attendees_info = { 11 | "uuid": "meu_uuid_attendee3", 12 | "name": "atendee name3", 13 | "email": "email3@email.com", 14 | "event_id": event_id 15 | } 16 | attendees_repository = AttendeesRepository() 17 | response = attendees_repository.insert_attendee(attendees_info) 18 | print(response) 19 | 20 | @pytest.mark.skip(reason="...") 21 | def test_get_attendee_badge_by_id(): 22 | attendde_id = "meu_uuid_attendee" 23 | attendees_repository = AttendeesRepository() 24 | attendee = attendees_repository.get_attendee_badge_by_id(attendde_id) 25 | 26 | print(attendee) 27 | print(attendee.title) 28 | -------------------------------------------------------------------------------- /init/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE "events" ( 2 | "id" TEXT NOT NULL PRIMARY KEY, 3 | "title" TEXT NOT NULL, 4 | "details" TEXT, 5 | "slug" TEXT NOT NULL, 6 | "maximum_attendees" INTEGER 7 | ); 8 | 9 | CREATE TABLE "attendees" ( 10 | "id" TEXT NOT NULL PRIMARY KEY, 11 | "name" TEXT NOT NULL, 12 | "email" TEXT NOT NULL, 13 | "event_id" TEXT NOT NULL, 14 | "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, 15 | CONSTRAINT "attendees_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "events" ("id") ON DELETE RESTRICT ON UPDATE CASCADE 16 | ); 17 | 18 | CREATE TABLE "check_ins" ( 19 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 20 | "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, 21 | "attendeeId" TEXT NOT NULL, 22 | CONSTRAINT "check_ins_attendeeId_fkey" FOREIGN KEY ("attendeeId") REFERENCES "attendees" ("id") ON DELETE RESTRICT ON UPDATE CASCADE 23 | ); 24 | 25 | CREATE UNIQUE INDEX "events_slug_key" ON "events"("slug"); 26 | CREATE UNIQUE INDEX "attendees_event_id_email_key" ON "attendees"("event_id", "email"); 27 | CREATE UNIQUE INDEX "check_ins_attendeeId_key" ON "check_ins"("attendeeId"); 28 | -------------------------------------------------------------------------------- /src/main/routes/event_routes.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, jsonify, request 2 | from src.http_types.http_request import HttpRequest 3 | from src.data.event_handler import EventHandler 4 | from src.errors.error_handler import handle_error 5 | 6 | event_route_bp = Blueprint("event_route", __name__) 7 | 8 | @event_route_bp.route("/events", methods=["POST"]) 9 | def create_event(): 10 | try: 11 | http_request = HttpRequest(body=request.json) 12 | event_handler = EventHandler() 13 | 14 | http_response = event_handler.register(http_request) 15 | return jsonify(http_response.body), http_response.status_code 16 | except Exception as exception: 17 | http_response = handle_error(exception) 18 | return jsonify(http_response.body), http_response.status_code 19 | 20 | @event_route_bp.route("/events/", methods=["GET"]) 21 | def get_event(event_id): 22 | try: 23 | event_handler = EventHandler() 24 | http_request = HttpRequest(param={ "event_id": event_id }) 25 | 26 | http_response = event_handler.find_by_id(http_request) 27 | return jsonify(http_response.body), http_response.status_code 28 | except Exception as exception: 29 | http_response = handle_error(exception) 30 | return jsonify(http_response.body), http_response.status_code 31 | -------------------------------------------------------------------------------- /src/data/event_handler.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | from src.models.repository.events_repository import EventsRepository 3 | from src.http_types.http_request import HttpRequest 4 | from src.http_types.http_response import HttpResponse 5 | from src.errors.error_types.http_not_found import HttpNotFoundError 6 | 7 | class EventHandler: 8 | def __init__(self) -> None: 9 | self.__events_repository = EventsRepository() 10 | 11 | def register(self, http_request: HttpRequest) -> HttpResponse: 12 | body = http_request.body 13 | body["uuid"] = str(uuid.uuid4()) 14 | self.__events_repository.insert_event(body) 15 | 16 | return HttpResponse( 17 | body={ "eventId": body["uuid"] }, 18 | status_code=200 19 | ) 20 | 21 | def find_by_id(self, http_request: HttpRequest) -> HttpResponse: 22 | event_id = http_request.param["event_id"] 23 | event = self.__events_repository.get_event_by_id(event_id) 24 | if not event: raise HttpNotFoundError("Evento não encontrado") 25 | 26 | event_attendees_count = self.__events_repository.count_event_attendees(event_id) 27 | 28 | return HttpResponse( 29 | body={ 30 | "event": { 31 | "id": event.id, 32 | "title": event.title, 33 | "detail": event.details, 34 | "slug": event.slug, 35 | "maximumAttendees": event.maximum_attendees, 36 | "attendeesAmount": event_attendees_count["attendeesAmount"] 37 | } 38 | }, 39 | status_code=200 40 | ) 41 | -------------------------------------------------------------------------------- /src/main/routes/attendees_routes.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, jsonify, request 2 | from src.http_types.http_request import HttpRequest 3 | from src.data.attendees_handler import AttendeesHandler 4 | from src.errors.error_handler import handle_error 5 | 6 | attendees_route_bp = Blueprint("attendees_route", __name__) 7 | 8 | @attendees_route_bp.route("/events//register", methods=["POST"]) 9 | def create_attendees(event_id): 10 | try: 11 | attendees_handle = AttendeesHandler() 12 | http_request = HttpRequest(param={ "event_id": event_id }, body=request.json) 13 | 14 | http_response = attendees_handle.registry(http_request) 15 | return jsonify(http_response.body), http_response.status_code 16 | except Exception as exception: 17 | http_response = handle_error(exception) 18 | return jsonify(http_response.body), http_response.status_code 19 | 20 | @attendees_route_bp.route("/attendees//badge", methods=["GET"]) 21 | def get_attendees_batch(attendee_id): 22 | try: 23 | attendees_handle = AttendeesHandler() 24 | http_request = HttpRequest(param={ "attendee_id": attendee_id }) 25 | 26 | http_response = attendees_handle.find_attendee_badge(http_request) 27 | return jsonify(http_response.body), http_response.status_code 28 | except Exception as exception: 29 | http_response = handle_error(exception) 30 | return jsonify(http_response.body), http_response.status_code 31 | 32 | @attendees_route_bp.route("/events//attendees", methods=["GET"]) 33 | def get_attendees(event_id): 34 | try: 35 | attendees_handle = AttendeesHandler() 36 | http_request = HttpRequest(param={ "event_id": event_id }) 37 | 38 | http_response = attendees_handle.find_attendees_from_event(http_request) 39 | return jsonify(http_response.body), http_response.status_code 40 | except Exception as exception: 41 | http_response = handle_error(exception) 42 | return jsonify(http_response.body), http_response.status_code 43 | -------------------------------------------------------------------------------- /src/models/repository/events_repository.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from src.models.settings.connection import db_connection_handler 3 | from src.models.entities.events import Events 4 | from src.models.entities.attendees import Attendees 5 | from sqlalchemy.exc import IntegrityError 6 | from sqlalchemy.orm.exc import NoResultFound 7 | from src.errors.error_types.http_conflict import HttpConflictError 8 | 9 | class EventsRepository: 10 | def insert_event(self, eventsInfo: Dict) -> Dict: 11 | with db_connection_handler as database: 12 | try: 13 | event = Events( 14 | id=eventsInfo.get("uuid"), 15 | title=eventsInfo.get("title"), 16 | details=eventsInfo.get("details"), 17 | slug=eventsInfo.get("slug"), 18 | maximum_attendees=eventsInfo.get("maximum_attendees"), 19 | ) 20 | database.session.add(event) 21 | database.session.commit() 22 | 23 | return eventsInfo 24 | except IntegrityError: 25 | raise HttpConflictError('Evento ja cadastrado!') 26 | except Exception as exception: 27 | database.session.rollback() 28 | raise exception 29 | 30 | def get_event_by_id(self, event_id: str) -> Events: 31 | with db_connection_handler as database: 32 | try: 33 | event = ( 34 | database.session 35 | .query(Events) 36 | .filter(Events.id==event_id) 37 | .one() 38 | ) 39 | return event 40 | except NoResultFound: 41 | return None 42 | 43 | def count_event_attendees(self, event_id: str) -> Dict: 44 | with db_connection_handler as database: 45 | event_count = ( 46 | database.session 47 | .query(Events) 48 | .join(Attendees, Events.id == Attendees.event_id) 49 | .filter(Events.id==event_id) 50 | .with_entities( 51 | Events.maximum_attendees, 52 | Attendees.id 53 | ) 54 | .all() 55 | ) 56 | if not len(event_count): 57 | return { 58 | "maximumAttendees": 0, 59 | "attendeesAmount": 0, 60 | } 61 | 62 | return { 63 | "maximumAttendees": event_count[0].maximum_attendees, 64 | "attendeesAmount": len(event_count), 65 | } 66 | -------------------------------------------------------------------------------- /src/data/attendees_handler.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | from src.models.repository.attendees_repository import AttendeesRepository 3 | from src.models.repository.events_repository import EventsRepository 4 | from src.http_types.http_request import HttpRequest 5 | from src.http_types.http_response import HttpResponse 6 | from src.errors.error_types.http_not_found import HttpNotFoundError 7 | from src.errors.error_types.http_conflict import HttpConflictError 8 | 9 | 10 | class AttendeesHandler: 11 | def __init__(self) -> None: 12 | self.__attendees_repository = AttendeesRepository() 13 | self.__events_repository = EventsRepository() 14 | 15 | def registry(self, http_request: HttpRequest) -> HttpResponse: 16 | body = http_request.body 17 | event_id = http_request.param["event_id"] 18 | 19 | event_attendees_count = self.__events_repository.count_event_attendees(event_id) 20 | if ( 21 | event_attendees_count["attendeesAmount"] 22 | and event_attendees_count["maximumAttendees"] < event_attendees_count["attendeesAmount"] 23 | ): raise HttpConflictError("Evento Lotado") 24 | 25 | body["uuid"] = str(uuid.uuid4()) 26 | body["event_id"] = event_id 27 | self.__attendees_repository.insert_attendee(body) 28 | 29 | return HttpResponse(body=None, status_code=201) 30 | 31 | def find_attendee_badge(self, http_request: HttpRequest) -> HttpResponse: 32 | attendee_id = http_request.param["attendee_id"] 33 | badge = self.__attendees_repository.get_attendee_badge_by_id(attendee_id) 34 | if not badge: raise HttpNotFoundError("Participante nao encontrado") 35 | 36 | return HttpResponse( 37 | body={ 38 | "badge": { 39 | "name": badge.name, 40 | "email": badge.email, 41 | "eventTitle": badge.title 42 | } 43 | }, 44 | status_code= 200 45 | ) 46 | 47 | def find_attendees_from_event(self, http_request: HttpRequest) -> HttpResponse: 48 | event_id = http_request.param["event_id"] 49 | attendees = self.__attendees_repository.get_attendees_by_event_id(event_id) 50 | if not attendees: raise HttpNotFoundError("Participantes nao encontrados") 51 | 52 | formatted_attendees = [] 53 | for atteendee in attendees: 54 | formatted_attendees.append( 55 | { 56 | "id": atteendee.id, 57 | "name": atteendee.name, 58 | "email": atteendee.email, 59 | "checkedInAt": atteendee.checkedInAt, 60 | "createdAt": atteendee.createdAt 61 | } 62 | ) 63 | 64 | return HttpResponse( 65 | body={ "attendees": formatted_attendees }, 66 | status_code=200 67 | ) -------------------------------------------------------------------------------- /src/models/repository/attendees_repository.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List 2 | from src.models.settings.connection import db_connection_handler 3 | from src.models.entities.attendees import Attendees 4 | from src.models.entities.check_ins import CheckIns 5 | from src.models.entities.events import Events 6 | from sqlalchemy.exc import IntegrityError 7 | from sqlalchemy.orm.exc import NoResultFound 8 | from src.errors.error_types.http_conflict import HttpConflictError 9 | 10 | class AttendeesRepository: 11 | def insert_attendee(self, attendde_info: Dict) -> Dict: 12 | with db_connection_handler as database: 13 | try: 14 | attendee = ( 15 | Attendees( 16 | id=attendde_info.get("uuid"), 17 | name=attendde_info.get("name"), 18 | email=attendde_info.get("email"), 19 | event_id=attendde_info.get("event_id") 20 | ) 21 | ) 22 | database.session.add(attendee) 23 | database.session.commit() 24 | 25 | return attendde_info 26 | except IntegrityError: 27 | raise HttpConflictError('Participante ja cadastrado!') 28 | except Exception as exception: 29 | database.session.rollback() 30 | raise exception 31 | 32 | def get_attendee_badge_by_id(self, attendee_id: str): 33 | with db_connection_handler as database: 34 | try: 35 | attendee = ( 36 | database.session 37 | .query(Attendees) 38 | .join(Events, Events.id == Attendees.event_id) 39 | .filter(Attendees.id==attendee_id) 40 | .with_entities( 41 | Attendees.name, 42 | Attendees.email, 43 | Events.title 44 | ) 45 | .one() 46 | ) 47 | return attendee 48 | except NoResultFound: 49 | return None 50 | 51 | def get_attendees_by_event_id(self, event_id: str) -> List[Attendees]: 52 | with db_connection_handler as database: 53 | attendees = ( 54 | database.session 55 | .query(Attendees) 56 | .outerjoin(CheckIns, CheckIns.attendeeId==Attendees.id) 57 | .filter(Attendees.event_id==event_id) 58 | .with_entities( 59 | Attendees.id, 60 | Attendees.name, 61 | Attendees.email, 62 | CheckIns.created_at.label('checkedInAt'), 63 | Attendees.created_at.label('createdAt') 64 | ) 65 | .all() 66 | ) 67 | return attendees --------------------------------------------------------------------------------