{"id":18339206,"url":"https://github.com/akotronis/dit189","last_synced_at":"2026-04-09T07:02:33.450Z","repository":{"id":180214190,"uuid":"646133273","full_name":"akotronis/DIT189","owner":"akotronis","description":"Web Information Systems and IoT (Tsadimas)","archived":false,"fork":false,"pushed_at":"2023-07-16T23:28:27.000Z","size":775,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-15T12:47:35.901Z","etag":null,"topics":["docker","docker-compose","flask-smorest","keykloak","mailhog","oop","postgres","python","react","rest-api","sqlalchemy","swagger"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akotronis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-27T11:49:14.000Z","updated_at":"2024-09-03T22:08:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"ec54c010-d831-4da5-a90e-d074b47fa9b4","html_url":"https://github.com/akotronis/DIT189","commit_stats":null,"previous_names":["akotronis/dit189"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akotronis%2FDIT189","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akotronis%2FDIT189/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akotronis%2FDIT189/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akotronis%2FDIT189/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akotronis","download_url":"https://codeload.github.com/akotronis/DIT189/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248108708,"owners_count":21049182,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","flask-smorest","keykloak","mailhog","oop","postgres","python","react","rest-api","sqlalchemy","swagger"],"created_at":"2024-11-05T20:16:51.538Z","updated_at":"2025-12-30T21:53:06.325Z","avatar_url":"https://github.com/akotronis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# General\n\nRepo for the project of 2nd semester (2023-2024) course **Web Information Systems and IoT** of the postgraduate program **_Informatics and Telematics_** of **Harokopio University**.\n\nIt implements the **consensual divorce** web service as described in [gov.gr](https://dvs.gov.gr/egxeiridio-xrisis).\n\n# Components/Services\n- Keycloak IAM for user management\n- A Postgres database for Keycloak\n- A Flask for backend main app component\n- A Postgres database for Flask main app data\n- ...\n\n# Tools/Technologies: \n- Microservices: **Docker/Docker Compose, Keycloak, Postgres, ...**\n- Backend: **Python, flask/flask-smorest, postgres, sqlalchemy/flask-sqlalchemy, marshmallow, python-keycloak, swagger**\n- Frontend: **React, ...**\n- Notifications: **...**\n- Devops/Deployment: **...**\n\n# Implementation\n\n## Backend Flask app\n\n### Models\n\nDatabase models were created according to the logic indicated in the below diagram\n\n[Database diagram](https://drawsql.app/teams/akotronis-team/diagrams/dit189-1)\n\n(Folder **models**)\n\n- `user`\n- `marriage`\n- `user_marriage`\n- `divorce`\n- `user_divorce`\n\nImplementation with [`flask-sqlalchemy`](https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/)\n\n### Data transfer validation/(de)serialization\n\nImplemented with [`marshmallow`](https://marshmallow.readthedocs.io/en/stable/)\n\n(Folder **schemas**)\n\n- `user`\n- `divorce`\n- `user_divorce`\n- `marriage`\n- `refresh` (Repopulates database. For development/presentation puprposes)\n\n### Authentication/Authotization\n\n- User authentication implemented with [Keycloak](https://www.keycloak.org/), along with the python library [python-keycloak](https://pypi.org/project/python-keycloak/)  \n- A [decorator is implemented](https://github.com/akotronis/DIT189/blob/main/app/api/keycloak.py#L157) which performs user authentication and authorization based on role using *Header Authorization Bearer token*  \n- In order to do authentication/authorization from swwagger interface, click *Authorize* button on the top right and paste the user token  \n  This will add the *Authorization Bearer \u003ctoken\u003e* on each request header,\n\n### Endpoints\n\n(Folder **resources**)\n\n- `user`\n- `marriage`\n- `divorce`\n- `rules`\n- `refresh`\n\n#### Users\n\n- `/users` \u0026rarr; **GET**: Return all users in flask app db\n- `/users` \u0026rarr; **POST**: Create a user with a specific role in Keycloak\n- `/users/\u003cuser_id\u003e` \u0026rarr; **GET**: Get an api db user's token if user is in Keycloak\n\n#### Marriages\n\n- `/marriages` \u0026rarr; **GET**: Return all marriages\n\n#### Cases/Divorces\n\n- `/cases` \u0026rarr; **GET**: Return all divorces\n- `/cases` \u0026rarr; **POST**: Create a divorce\n- `/cases/\u003ccase_id\u003e` \u0026rarr; **GET**: Get a divorce\n- `/cases/\u003ccase_id\u003e` \u0026rarr; **PUT**: Update a divorce\n\n#### Rules\n\n- `/rules` \u0026rarr; **GET**: Return info about all available endpoints/methods.\n\n#### Refresh\n\n- `/refresh` \u0026rarr; **GET**: Repopulates the flask app database with users and marriages (for development/presentation purposes)  \n  If `drop` query param is set to `False`, it just returns all the users with their attributes, so we can test use cases.\n\n#### Documentation\n\nDetailed documentation on endpoints and corresponding schemas available on documentation endpoints\n\n- `http://localhost:5000/swagger-ui`, or  \n  \u003cp align=\"left\"\u003e\u003cimg src=\"./app/resources/swagger.jpg\" alt=\"swagger\" width=\"800\"/\u003e\u003c/p\u003e\n- `http://localhost:5000/redoc`\n\n\u003c!-- ![swagger](./app/resources/swagger.jpg) --\u003e\n\n\n# Instructions\n\nMake `.env` file as in `.env.example`\n\n`WORK_ENV=prod/dev`. If empty, defaults to `dev`. See `config.py/setup.py` for details.\n\n## Run locally with docker-compose\n\nWith Docker (Desktop) installed, on the folder where `docker-compose.yaml` is:\n\n- `\u003e\u003e\u003e docker-compose up`\n- In order to work with Keycloak, after the services are up, a realm and two clients (backend and frontend) have to be created in Keycloak and  \n  the variables `REAL, CLIENT_ID, CLIENT_SECRET` in `.env` file have to be populated with the corresponding values.  \n  After this the services have to be restarted.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakotronis%2Fdit189","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakotronis%2Fdit189","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakotronis%2Fdit189/lists"}