{"id":21455459,"url":"https://github.com/alvertogit/codetest","last_synced_at":"2026-04-05T20:40:05.428Z","repository":{"id":52979249,"uuid":"128662646","full_name":"alvertogit/codetest","owner":"alvertogit","description":"Code test Python Django Django5 PostgreSQL Docker NGINX Gunicorn microservices REST API Jupyter Lab Notebook","archived":false,"fork":false,"pushed_at":"2025-03-16T11:28:55.000Z","size":393,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-16T12:27:48.181Z","etag":null,"topics":["django","django5","docker","jupyter-lab","jupyter-notebook","postgresql","python","rest-api"],"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/alvertogit.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":"2018-04-08T16:54:40.000Z","updated_at":"2025-03-16T11:28:59.000Z","dependencies_parsed_at":"2024-01-01T19:29:55.877Z","dependency_job_id":"286b078b-0f78-4576-b79d-e66d721b3f5f","html_url":"https://github.com/alvertogit/codetest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alvertogit%2Fcodetest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alvertogit%2Fcodetest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alvertogit%2Fcodetest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alvertogit%2Fcodetest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alvertogit","download_url":"https://codeload.github.com/alvertogit/codetest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243966065,"owners_count":20375992,"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":["django","django5","docker","jupyter-lab","jupyter-notebook","postgresql","python","rest-api"],"created_at":"2024-11-23T05:12:13.949Z","updated_at":"2026-04-05T20:40:05.421Z","avatar_url":"https://github.com/alvertogit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CODE TEST \u003c!-- omit in toc --\u003e\n\nThis repository stores a code test compose of two exercises to demonstrate skills mainly with [Python], [Django], [Gunicorn], [NGINX], [PostgreSQL], [Docker], [Jupyter Notebook], [microservices] and [REST API].\n\n- [DEPENDENCIES](#dependencies)\n- [CODE TEST CONTENT](#code-test-content)\n- [EXERCISE 1: PYTHON](#exercise-1-python)\n  - [EXERCISE 1 REQUIREMENTS](#exercise-1-requirements)\n  - [EXERCISE 1 NOTES](#exercise-1-notes)\n  - [EXERCISE 1 FOLDER CONTENT](#exercise-1-folder-content)\n  - [HOW TO RUN EXERCISE 1](#how-to-run-exercise-1)\n- [EXERCISE 2: DATA \\\u0026 API TEST](#exercise-2-data--api-test)\n  - [EXERCISE 2 REQUIREMENTS](#exercise-2-requirements)\n  - [EXERCISE 2 NOTES](#exercise-2-notes)\n  - [BONUS](#bonus)\n  - [EXERCISE 2 FOLDER CONTENT](#exercise-2-folder-content)\n  - [EXERCISE 2 ARCHITECTURE](#exercise-2-architecture)\n  - [HOW TO RUN EXERCISE 2 **WITH DOCKER COMPOSE**](#how-to-run-exercise-2-with-docker-compose)\n    - [TESTS](#tests)\n- [CREDITS](#credits)\n\n## DEPENDENCIES\n\nThe code has been tested using:\n\n- [Python] (3.12): an interpreted high-level programming language for general-purpose programming.\n- [Jupyter Lab] (4.5): a web-based interactive development environment for [Jupyter Notebooks], code and data.\n- [Django] (6.0): a high-level [Python] Web framework that encourages rapid development and clean, pragmatic design.\n- [Gunicorn] (25.3): a [Python] [WSGI] HTTP Server for UNIX.\n- [NGINX] (1.29): a free, open-source, high-performance HTTP server, reverse proxy, and IMAP/POP3 proxy server.\n- [PostgreSQL] (18.3): an object-relational database management system (ORDBMS) with an emphasis on extensibility and standards compliance.\n- [Docker] (28.5): an open platform for developers and sysadmins to build, ship, and run distributed applications, whether on laptops, data center VMs, or the cloud.\n- [Docker Compose] (2.40): a tool for defining and running multi-container [Docker] applications.\n\nVirtual environment (\u003cenv_name\u003e=**.venv**) can be generated with **requirements.txt** file found in codetest main folder.\n\nCommand to configure virtual environment with [venv]:\n\n```bash\n~/codetest$ python3 -m venv .venv\n~/codetest$ source .venv/bin/activate\n(.venv)~/codetest$ python3 -m pip install pip==26.0.1\n(.venv)~/codetest$ python3 -m pip install setuptools==82.0.1\n(.venv)~/codetest$ python3 -m pip install -r requirements.txt\n(.venv)~/codetest$ pre-commit install\n```\n\n## CODE TEST CONTENT\n\nCodetest main folder contains two folders for Exercise 1 and Exercise 2.\n\n```bash\ncodetest\n├── .gitignore\n├── .pre-commit-config.yaml\n├── exercise1\n├── exercise2\n├── README.md\n└── requirements.txt\n```\n\n## EXERCISE 1: PYTHON\n\n### EXERCISE 1 REQUIREMENTS\n\nWrite a small app that takes an integer and return a string representation of that integer with commas separating\ngroups of 3 digits. For example:\n\n```python\nprint(translate(1234))\n'1,234'\nprint(translate(123456789))\n'123,456,789'\n```\n\n### EXERCISE 1 NOTES\n\n• Use [Python] as programming language.\n\n• Input/output methods doesn’t matter.\n\n### EXERCISE 1 FOLDER CONTENT\n\nThe **exercise1** folder contains three files:\n\n- **function.py**: It contents translate functions code for Exercise 1 including one solution with regular expression.\n\n- **main.py**: It is used to test translate functions.\n\n- **Exercise1.ipynb**: [Jupyter Notebook] to test translate functions.\n\n```bash\nexercise1\n├── docs\n├── Exercise1.ipynb\n├── function.py\n└── main.py\n```\n\n### HOW TO RUN EXERCISE 1\n\nThe way to run Exercise 1 is simple. Just go to **exercise1** folder and execute:\n\n```bash\n(.venv)~/codetest/exercise1$ python3 main.py\n```\n\nA good way to play with the **translate** and **translate_regex** functions is through a [Jupyter Lab]. One notebook is stored in the same **exercise1** folder, to run it use the command shown below:\n\n```bash\n(.venv)~/codetest/exercise1$ jupyter lab Exercise1.ipynb\n```\n\n![Jupyter notebook translate function](exercise1/docs/jupyter_notebook_translate_function.png)\n\n## EXERCISE 2: DATA \u0026 API TEST\n\n### EXERCISE 2 REQUIREMENTS\n\nWrite a small app that publish an [REST API] with these endpoints using data from **test.xml**:\n\n• Give me 20 products ordered by price.\n\n• Give me 20 products ordered by discount (price - custom_label_0).\n\n• Give me the most discounted 20 products.\n\n• Give me all products under the “Comedy” product type.\n\n### EXERCISE 2 NOTES\n\n• Use [Python] as programming language ([Django] framework preferred).\n\n• Don’t waste time in how consume the API or in the authentication. If it can be tested with Curl or Requests, is totally valid.\n\n### BONUS\n\n• Use [Docker Compose] to setup and run the [Django]/[PostgreSQL] app.\n\n### EXERCISE 2 FOLDER CONTENT\n\nThe **exercise2** folder contains:\n\n```bash\nexercise2\n├── docker-compose.yml\n├── docs\n├── mysite\n│   ├── .env.example\n│   ├── Dockerfile\n│   ├── manage.py\n│   ├── mysite\n│   │   ├── __init__.py\n│   │   ├── settings.py\n│   │   ├── urls.py\n│   │   ├── wsgi.py\n│   ├── products\n│   │   ├── admin.py\n│   │   ├── apps.py\n│   │   ├── __init__.py\n│   │   ├── models.py\n│   │   ├── serializers.py\n│   │   ├── tests.py\n│   │   ├── urls.py\n│   │   ├── views.py\n│   └── requirements.txt\n├── nginx\n│   └── conf.d\n│       └── local.conf\n└── postgresql\n    ├── codetest.sql\n    ├── Dockerfile\n    ├── importer.py\n    └── test.xml\n```\n\n- **docker-compose.yml**: creates the [Django] and [PostgreSQL] [Docker] containers in which the applications shall run.\n\n- **docs**: It stores Exercise 2 documentation.\n\n- **mysite**: It stores [Django]'s **products** app code.\n\n- **nginx**: It stores [NGINX]'s configuration.\n\n- **postgresql**: It stores the **test.xml** with data to be inserted into [PostgreSQL] and the **importer** app to do this process.\n\n### EXERCISE 2 ARCHITECTURE\n\nThe architecture created with [Docker Compose] uses three different [Docker] containers for:\n\n- [NGINX].\n- [Django] and [Gunicorn].\n- [PostgreSQL].\n\nThe following diagram illustrates the architecture in blocks:\n\n```mermaid\nflowchart LR;\n   Client\u003c--\u003eNGINX;\n   NGINX\u003c--brigde--\u003eGunicorn;\n   subgraph web;\n   Gunicorn\u003c--\u003eDjango;\n   end;\n   Django\u003c--brigde--\u003eid1[(PostgreSQL)]\n```\n\n### HOW TO RUN EXERCISE 2 **WITH DOCKER COMPOSE**\n\nThe steps and commands to run Exercise 2 with [Docker Compose] are described below.\n\nFirst create environment **.env** file using **.env.example** file as template inside **mysite** folder. Exercise 2 should run fine with default template settings.\n\nThen [Docker Compose] can be executed to build services.\n\n```bash\n~/codetest/exercise2$ docker compose build\n```\n\nNext step consists in executing [Docker Compose] up command.\n\n```bash\n~/codetest/exercise2$ docker compose up\n```\n\nIt is possible that for the first time the command keeps stopped at one point as shown below:\n\n```bash\n...\npostgres_db_1_81cb47c30feg | 2018-12-11 09:59:15.676 UTC [42] ERROR:  role \"postgres\" does not exist\npostgres_db_1_81cb47c30feg | 2018-12-11 09:59:15.676 UTC [42] STATEMENT:  REVOKE ALL ON SCHEMA public FROM postgres;\nexercise2_postgres_db_1_81cb47c30feg exited with code 3\n```\n\nIf this happens simply press 'Control+C', wait patiently to return to shell and repeat again the same command. If everything goes fine at the end it should appear something similar to:\n\n```bash\n...\npostgres_db_1_81cb47c30feg | 2018-12-11 09:59:27.670 UTC [1] LOG:  database system is ready to accept connections\n```\n\nThere are different ways to check that the server is running properly. One is opening a web browser such as Chrome or Firefox and paste the following URL:\n\n```bash\nhttp://127.0.0.1/products/\n```\n\nThe web browser should show something similar to:\n\n```bash\nHTTP 200 OK\nAllow: GET, HEAD, OPTIONS\nContent-Type: application/json\nVary: Accept\n\n{\n    \"price\": \"http://127.0.0.1/products/price/\",\n    \"discount\": \"http://127.0.0.1/products/discount/\",\n    \"mostdiscounted\": \"http://127.0.0.1/products/mostdiscounted/\",\n    \"typecomedy\": \"http://127.0.0.1/products/typecomedy/\"\n}\n```\n\nThe description of the URLs that are above:\n\n- \"price\" URL: Gets 20 products ordered by price.\n\n```bash\nHTTP 200 OK\nAllow: GET, POST, HEAD, OPTIONS\nContent-Type: application/json\nVary: Accept\n\n[\n    {\n        \"product_id\": \"AF5TW2\",\n        \"title\": \"Maxi-Cosi - AxissFix Autostol (61-105 cm)\",\n        \"product_type\": \"Car Seats \u003e Child car seats \u003e Child benefit\",\n        \"price\": \"3299.00\",\n        \"custom_label_0\": \"3135.00\"\n    },\n    {\n        \"product_id\": \"AN3WT9\",\n        \"title\": \"Maxi-Cosi - AxissFix Autostol (61-105 cm)\",\n        \"product_type\": \"Car Seats \u003e Child car seats \u003e Child benefit\",\n        \"price\": \"3299.00\",\n        \"custom_label_0\": \"3135.00\"\n    },\n    ...\n    ...\n    ...\n    {\n        \"product_id\": \"AG286U\",\n        \"title\": \"Maxi-Cosi - Citi Autostol (0-13 kg)\",\n        \"product_type\": \"Car Seats \u003e Child car seats \u003e Child benefit\",\n        \"price\": \"890.00\",\n        \"custom_label_0\": \"846.00\"\n    }\n]\n```\n\n- \"discount\" URL: Gets 20 products ordered by discount (price - custom_label_0).\n\n```bash\nHTTP 200 OK\nAllow: GET, POST, HEAD, OPTIONS\nContent-Type: application/json\nVary: Accept\n\n[\n    {\n        \"product_id\": \"AF84CU\",\n        \"title\": \"Sisley - Daily Line Reducer 30 ml\",\n        \"product_type\": \"Skincare \u003e Face \u003e Oils \u0026 Serums\",\n        \"price\": \"2399.00\",\n        \"custom_label_0\": \"2199.00\"\n    },\n    {\n        \"product_id\": \"AD529V\",\n        \"title\": \"Maxi-Cosi - AxissFix Autostol (61-105 cm)\",\n        \"product_type\": \"Car Seats \u003e Child car seats \u003e Child benefit\",\n        \"price\": \"3299.00\",\n        \"custom_label_0\": \"3135.00\"\n    },\n    ...\n    ...\n    ...\n    {\n        \"product_id\": \"AJ79SB\",\n        \"title\": \"Escentric Molecules - Escentric 04 EDT 100 ml\",\n        \"product_type\": \"Perfume \u003e Eau de Toilette\",\n        \"price\": \"679.00\",\n        \"custom_label_0\": \"612.00\"\n    }\n]\n```\n\n- \"mostdiscounted\" URL: Gets the most discounted 20 products.\n\n```bash\nHTTP 200 OK\nAllow: GET, POST, HEAD, OPTIONS\nContent-Type: application/json\nVary: Accept\n\n[\n    {\n        \"product_id\": \"AJ43CN\",\n        \"title\": \"Grusomme mig 2 - DVD\",\n        \"product_type\": \"Movies \u003e DVD \u003e Standard \u003e Adventure \u003e 7\",\n        \"price\": \"69.00\",\n        \"custom_label_0\": \"29.00\"\n    },\n    {\n        \"product_id\": \"AF75JP\",\n        \"title\": \"Marley \u0026 Me - DVD\",\n        \"product_type\": \"Movies \u003e DVD \u003e Standard \u003e Comedy \u003e Owen Wilson \u003e 7\",\n        \"price\": \"69.00\",\n        \"custom_label_0\": \"29.00\"\n    },\n    ...\n    ...\n    ...\n    {\n        \"product_id\": \"AC8M7R\",\n        \"title\": \"Melton - Numbers Rib Drenge Boxershorts 2 pk\",\n        \"product_type\": \"Apparel \u0026 Accessories \u003e Clothing\",\n        \"price\": \"99.00\",\n        \"custom_label_0\": \"59.00\"\n    }\n]\n```\n\n- \"typecomedy\" URL: Gets all products under “Comedy” product type.\n\n```bash\nHTTP 200 OK\nAllow: GET, POST, HEAD, OPTIONS\nContent-Type: application/json\nVary: Accept\n\n[\n    {\n        \"product_id\": \"AK628C\",\n        \"title\": \"Men in Black 3 (3D Blu-Ray)\",\n        \"product_type\": \"Movies \u003e 3D Blu-Ray \u003e Standard \u003e Comedy \u003e Will Smith\",\n        \"price\": \"109.00\",\n        \"custom_label_0\": \"79.00\"\n    },\n    {\n        \"product_id\": \"AC39B4\",\n        \"title\": \"Men in Black 3 (4K Blu-Ray)\",\n        \"product_type\": \"Movies \u003e 4K Blu-Ray \u003e Standard \u003e Comedy \u003e Will Smith\",\n        \"price\": \"269.00\",\n        \"custom_label_0\": \"229.00\"\n    },\n    ...\n    ...\n    ...\n    {\n        \"product_id\": \"AF52KX\",\n        \"title\": \"Glee: Hele Sæson 5 (6-disc) - DVD\",\n        \"product_type\": \"TV Series \u003e DVD \u003e Complete Edition \u003e Comedy \u003e Lea Michele \u003e 15\",\n        \"price\": \"109.00\",\n        \"custom_label_0\": \"69.00\"\n    }\n]\n```\n\n#### TESTS\n\nTo run tests execute inside web container the command to launch tests:\n\n```bash\n~/codetest/exercise2$ docker compose exec web bash\nroot@8800eecc88:/mysite# python manage.py test\nFound 6 test(s).\nCreating test database for alias 'default'...\nSystem check identified no issues (0 silenced).\n......\n----------------------------------------------------------------------\nRan 6 tests in 0.056s\n\nOK\nDestroying test database for alias 'default'...\n\n```\n\n## CREDITS\n\nauthor: alvertogit\ncopyright: 2018-2026\n\n[Python]: https://www.python.org/\n[Django]: https://www.djangoproject.com/\n[Gunicorn]: https://gunicorn.org/\n[WSGI]: https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface\n[NGINX]: https://www.nginx.com/\n[PostgreSQL]: https://www.postgresql.org/\n[Docker]: https://www.docker.com/\n[microservices]: https://en.wikipedia.org/wiki/Microservices\n[REST API]: https://en.wikipedia.org/wiki/Representational_state_transfer\n[Docker Compose]: https://github.com/docker/compose\n[venv]: https://docs.python.org/3/library/venv.html\n[Jupyter Lab]: https://jupyter.org/\n[Jupyter Notebook]: https://jupyter.org/\n[Jupyter Notebooks]: https://jupyter.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falvertogit%2Fcodetest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falvertogit%2Fcodetest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falvertogit%2Fcodetest/lists"}