Skip to content

Latest commit

 

History

History
93 lines (76 loc) · 5.47 KB

File metadata and controls

93 lines (76 loc) · 5.47 KB

Sync and Async Web Server

Objective

Develop web servers in Python in 2 versions: a first simple synchronous (sync) web server using only the socket module and second an asynchronous (async) web server using the aiohttp framework.

Requirements:

  1. Synchronous (Sync) Web Server:

    • Create a simple synchronous web server using the socket module.
    • The sync server should listen on localhost at port 8001.
    • Implement a single route /hello that responds with a plain text message "Hello, World!".
    • Demonstrate handling HTTP requests synchronously.
  2. Asynchronous (Async) Web Server:

    • Create an asynchronous web server using the aiohttp framework.
    • The async server should listen on localhost at port 8002.
    • Implement two routes:
      • Route 1: /hello - Respond with a plain text message "Hello, World!".
      • Route 2: /echo - Accept POST requests. Respond with the JSON representation of the received POST data.
    • Use asynchronous programming features provided by aiohttp.
    • Demonstrate the use of asynchronous functions, asyncio, and the aiohttp library to handle requests concurrently.
  3. External API:

    • Create a package in core directory for both servers to call any external Weather server with open API (I propose to use this one).
    • Add endpoint /weather for both servers and use a single common code without duplication.
    • Parse all incoming data with Pydantic models and handle it in console somewhere.

Additional Challenges (For both servers):

  1. Middleware:

    • Implement a middleware that adds a custom header to every response.
  2. Error Handling:

    • Implement error handling for common HTTP errors (e.g., 404 Not Found, 500 Internal Server Error).
  3. Dockerization (Optional):

    • Create a Dockerfile for each server to containerize both the sync and async applications.
  4. Tests:

    • Write unit tests using pytest for the main functionality of both the sync and async servers.
  5. Stress-test

    • Add in each server several endpoints to simulate I/O & CPU bound tasks and something else to simulate error on server-side e.g. /io_task, /cpu_task, /error_task, etc.
    • Install locust package in your local env and write a script to stress-test two servers.
    • It would be cool to plot a graph on the data obtained from locust and put it in the documentation.

Submission:

  • All Python code MUST be typed (the typing module to your rescue).
  • Implement the project according to the PEP8 standard should be described in the tool section of the pyproject.toml for linters with some modifications:
    • String length should be 120 characters.
    • Count of lines after import should be 2.
    • The rest is by specification.
  • Pytest configs also should be in in the tool section of the pyproject.toml.
  • Commit style, click. Commits should contain small logical portions of the code being modified. A clear commit name is required, descriptions within commits are welcome. The commit header should be up to 50 characters and the description up to 72 characters, read more.
  • Branch style, click. It is suggested to use GitFlow. Don't forget to delete merged or close branches based on PR status. Development should be done in separate branches, it is not allowed to commit or merge changes directly into master or develop.
  • Commits, branches and PR's should contain small pieces of separate logic so that it can be revisited. There is EXAMPLE, how to decompose and get started (documentation should also be also updated):
    • The first PR would be enough to see poetry installed and a project structure.
    • The second PR sync server.
    • The third PR async server.
    • The fourth PR Docker.
    • The fifth PR external API call.
  • Try to follow all OOP & design principles.
  • Submit the codebase along with a detailed README explaining how to set up and run the monolithic application, any additional features implemented, and any challenges faced. Here is a good cheat-list how to style documentation.
  • Fork this repository and do your development there.

Note:

  • Use Python 3.10 or above.
  • Feel free to use any additional libraries or tools you find suitable for the task.
  • Try decomposing tasks into chunks and branches as described above.
  • All highlighted words should be read in the documentation or familiarized with what they are.
  • Follow best practices in terms of code readability, structure, and documentation.

Suggested project structure:

./
├── src/
│   ├── app/
│   │   ├── async/
│   │   │   ├── __init__.py
│   │   │   └── main.py
│   │   ├── sync/
│   │   │   ├── __init__.py
│   │   │   └── main.py
│   │   └── __init__.py
│   ├── core/
│   │   └── __init__.py
│   └── __init__.py
├── README.md
└── task.md