From 1b6c4a0eeef1681d2e1b3fb38debabfce6782482 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Mon, 19 May 2025 16:05:48 +0530 Subject: [PATCH 01/15] feat: add support for litestar --- frameworks/Python/litestar/README.md | 37 +++ .../Python/litestar/app-socketify-asgi.py | 42 +++ frameworks/Python/litestar/app.py | 130 ++++++++++ frameworks/Python/litestar/app_orm.py | 167 ++++++++++++ .../Python/litestar/benchmark_config.json | 242 ++++++++++++++++++ frameworks/Python/litestar/config.toml | 184 +++++++++++++ .../litestar-gunicorn-orjson.dockerfile | 18 ++ .../litestar/litestar-gunicorn-orm.dockerfile | 20 ++ .../litestar-hypercorn-orjson.dockerfile | 18 ++ .../litestar/litestar-hypercorn.dockerfile | 18 ++ .../litestar-nginx-unit-orjson.dockerfile | 20 ++ .../litestar/litestar-nginx-unit.dockerfile | 20 ++ .../litestar-socketify-asgi-pypy.dockerfile | 16 ++ .../litestar-socketify-asgi.dockerfile | 19 ++ .../litestar-uvicorn-orjson.dockerfile | 18 ++ .../litestar/litestar-uvicorn.dockerfile | 18 ++ .../Python/litestar/litestar.dockerfile | 18 ++ frameworks/Python/litestar/litestar_conf.py | 12 + .../litestar/nginx-unit-config-orjson.sh | 26 ++ .../Python/litestar/nginx-unit-config.sh | 26 ++ .../Python/litestar/requirements-gunicorn.txt | 1 + .../litestar/requirements-hypercorn.txt | 1 + .../Python/litestar/requirements-orjson.txt | 1 + .../litestar/requirements-socketify-pypy.txt | 2 + .../litestar/requirements-socketify.txt | 3 + .../litestar/requirements-sqlalchemy.txt | 3 + .../Python/litestar/requirements-uvicorn.txt | 3 + frameworks/Python/litestar/requirements.txt | 4 + .../Python/litestar/templates/fortune.html | 10 + .../Python/litestar/templates/fortune.jinja | 10 + 30 files changed, 1107 insertions(+) create mode 100755 frameworks/Python/litestar/README.md create mode 100755 frameworks/Python/litestar/app-socketify-asgi.py create mode 100755 frameworks/Python/litestar/app.py create mode 100755 frameworks/Python/litestar/app_orm.py create mode 100755 frameworks/Python/litestar/benchmark_config.json create mode 100644 frameworks/Python/litestar/config.toml create mode 100644 frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile create mode 100644 frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile create mode 100644 frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile create mode 100644 frameworks/Python/litestar/litestar-hypercorn.dockerfile create mode 100644 frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile create mode 100644 frameworks/Python/litestar/litestar-nginx-unit.dockerfile create mode 100644 frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile create mode 100644 frameworks/Python/litestar/litestar-socketify-asgi.dockerfile create mode 100644 frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile create mode 100644 frameworks/Python/litestar/litestar-uvicorn.dockerfile create mode 100644 frameworks/Python/litestar/litestar.dockerfile create mode 100644 frameworks/Python/litestar/litestar_conf.py create mode 100755 frameworks/Python/litestar/nginx-unit-config-orjson.sh create mode 100755 frameworks/Python/litestar/nginx-unit-config.sh create mode 100644 frameworks/Python/litestar/requirements-gunicorn.txt create mode 100644 frameworks/Python/litestar/requirements-hypercorn.txt create mode 100644 frameworks/Python/litestar/requirements-orjson.txt create mode 100644 frameworks/Python/litestar/requirements-socketify-pypy.txt create mode 100644 frameworks/Python/litestar/requirements-socketify.txt create mode 100644 frameworks/Python/litestar/requirements-sqlalchemy.txt create mode 100644 frameworks/Python/litestar/requirements-uvicorn.txt create mode 100644 frameworks/Python/litestar/requirements.txt create mode 100644 frameworks/Python/litestar/templates/fortune.html create mode 100644 frameworks/Python/litestar/templates/fortune.jinja diff --git a/frameworks/Python/litestar/README.md b/frameworks/Python/litestar/README.md new file mode 100755 index 00000000000..f61cec947c7 --- /dev/null +++ b/frameworks/Python/litestar/README.md @@ -0,0 +1,37 @@ +# Litestar Benchmarking Test + +This is the Litestar portion of a [benchmarking tests suite](../../) +comparing a variety of web development platforms. + +The information below is specific to Litestar. For further guidance, +review the [documentation](https://github.com/TechEmpower/FrameworkBenchmarks/wiki). +Also note that there is additional information provided in +the [Python README](../). + +## Description + +[**Litestar**](https://github.com/tiangolo/fastapi) is a modern, fast (high-performance), web framework for building APIs with Python 3.6+. + +The key features are: + +* **Fast**: Very high performance, on par with **NodeJS** and **Go**. + +* **Fast to code**: Increase the speed to develop features by about 200% to 300% *. +* **Less bugs**: Reduce about 40% of human (developer) induced errors. * +* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. +* **Easy**: Designed to be easy to use and learn. Less time reading docs. +* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Less bugs. +* **Robust**: Get production-ready code. With automatic interactive documentation. +* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI and JSON Schema. + +* estimation based on tests on an internal development team, building production applications. + +## Test Paths & Sources + +All of the test implementations are located within a single file ([app.py](app.py)). + + +## Resources + +* [Litestar source code on GitHub](https://github.com/litestar-org/litestar) +* [Litestar website - documentation](https://litestar.dev) diff --git a/frameworks/Python/litestar/app-socketify-asgi.py b/frameworks/Python/litestar/app-socketify-asgi.py new file mode 100755 index 00000000000..da691dac931 --- /dev/null +++ b/frameworks/Python/litestar/app-socketify-asgi.py @@ -0,0 +1,42 @@ +import os +import multiprocessing +import logging + +import orjson +from litestar import Litestar, get, MediaType +from socketify import ASGI + + +app = Litestar() + +@get("/json") +async def json_serialization(): + return orjson.dumps({"message": "Hello, world!"}) + +@get("/plaintext", media_type=MediaType.TEXT) +async def plaintext(): + return b"Hello, world!" + + +_is_travis = os.environ.get('TRAVIS') == 'true' + +workers = int(multiprocessing.cpu_count()) +if _is_travis: + workers = 2 + +def run_app(): + ASGI(app).listen(8080, lambda config: logging.info(f"Listening on port http://localhost:{config.port} now\n")).run() + + +def create_fork(): + n = os.fork() + # n greater than 0 means parent process + if not n > 0: + run_app() + + +# fork limiting the cpu count - 1 +for i in range(1, workers): + create_fork() + +run_app() # run app on the main process too :) \ No newline at end of file diff --git a/frameworks/Python/litestar/app.py b/frameworks/Python/litestar/app.py new file mode 100755 index 00000000000..d93507623b3 --- /dev/null +++ b/frameworks/Python/litestar/app.py @@ -0,0 +1,130 @@ +import multiprocessing +from contextlib import asynccontextmanager +from pathlib import Path + +import asyncpg +import os + +import orjson +from litestar import Litestar, Request, get, MediaType + +from random import randint, sample + +from litestar.contrib.jinja import JinjaTemplateEngine +from litestar.response import Template +from litestar.template import TemplateConfig + +READ_ROW_SQL = 'SELECT "id", "randomnumber" FROM "world" WHERE id = $1' +WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2' +ADDITIONAL_ROW = [0, "Additional fortune added at request time."] +MAX_POOL_SIZE = 1000//multiprocessing.cpu_count() +MIN_POOL_SIZE = max(int(MAX_POOL_SIZE / 2), 1) + + +def get_num_queries(queries): + try: + query_count = int(queries) + except (ValueError, TypeError): + return 1 + + if query_count < 1: + return 1 + if query_count > 500: + return 500 + return query_count + + +connection_pool = None + + + +async def setup_database(): + return await asyncpg.create_pool( + user=os.getenv("PGUSER", "benchmarkdbuser"), + password=os.getenv("PGPASS", "benchmarkdbpass"), + database="hello_world", + host="tfb-database", + port=5432, + min_size=MIN_POOL_SIZE, + max_size=MAX_POOL_SIZE, + ) + + +@asynccontextmanager +async def lifespan(app: Litestar): + # Set up the database connection pool + app.state.connection_pool = await setup_database() + yield + # Close the database connection pool + await app.state.connection_pool.close() + + +app = Litestar(lifespan=[lifespan], template_config=TemplateConfig( + directory=Path("templates"), + engine=JinjaTemplateEngine, + ),) + + +@get("/json") +async def json_serialization(): + return orjson.dumps({"message": "Hello, world!"}) + + +@get("/db") +async def single_database_query(): + row_id = randint(1, 10000) + async with app.state.connection_pool.acquire() as connection: + number = await connection.fetchval(READ_ROW_SQL, row_id) + + return orjson.dumps({"id": row_id, "randomNumber": number}) + + +@get("/queries") +async def multiple_database_queries(queries = None): + num_queries = get_num_queries(queries) + row_ids = sample(range(1, 10000), num_queries) + worlds = [] + + async with app.state.connection_pool.acquire() as connection: + statement = await connection.prepare(READ_ROW_SQL) + for row_id in row_ids: + number = await statement.fetchval(row_id) + worlds.append({"id": row_id, "randomNumber": number}) + + return orjson.dumps(worlds) + + +@get("/fortunes") +async def fortunes(request: Request): + async with app.state.connection_pool.acquire() as connection: + fortunes = await connection.fetch("SELECT * FROM Fortune") + + fortunes.append(ADDITIONAL_ROW) + fortunes.sort(key=lambda row: row[1]) + return Template("fortune.html", context={"fortunes": fortunes, "request": request}) + + +@get("/updates") +async def database_updates(queries = None): + num_queries = get_num_queries(queries) + # To avoid deadlock + ids = sorted(sample(range(1, 10000 + 1), num_queries)) + numbers = sorted(sample(range(1, 10000), num_queries)) + updates = list(zip(ids, numbers)) + + worlds = [ + {"id": row_id, "randomNumber": number} for row_id, number in updates + ] + + async with app.state.connection_pool.acquire() as connection: + statement = await connection.prepare(READ_ROW_SQL) + for row_id, _ in updates: + await statement.fetchval(row_id) + await connection.executemany(WRITE_ROW_SQL, updates) + + return orjson.dumps(worlds) + + +@get("/plaintext", media_type=MediaType.TEXT) +async def plaintext(): + return b"Hello, world!" diff --git a/frameworks/Python/litestar/app_orm.py b/frameworks/Python/litestar/app_orm.py new file mode 100755 index 00000000000..27b8cc9c301 --- /dev/null +++ b/frameworks/Python/litestar/app_orm.py @@ -0,0 +1,167 @@ +import logging +import multiprocessing +import os +from contextlib import asynccontextmanager +from operator import attrgetter +from pathlib import Path +from random import randint, sample + +import ujson5 +from litestar.contrib.jinja import JinjaTemplateEngine +from litestar.response import Template +from litestar.template import TemplateConfig +from sqlalchemy import Column, Integer, String, select +from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm.attributes import flag_modified + +from litestar import Litestar, Request, MediaType, get + +logger = logging.getLogger(__name__) + +Base = declarative_base() + + +class World(Base): + __tablename__ = "world" + id = Column(Integer, primary_key=True) + randomnumber = Column(Integer) + + def __json__(self): + return {"id": self.id, "randomnumber": self.randomnumber} + + +sa_data = World.__table__ + + +class Fortune(Base): + __tablename__ = "fortune" + id = Column(Integer, primary_key=True) + message = Column(String) + + +sa_fortunes = Fortune.__table__ + +ADDITIONAL_FORTUNE = Fortune( + id=0, message="Additional fortune added at request time." +) +MAX_POOL_SIZE = 1000//multiprocessing.cpu_count() + +sort_fortunes_key = attrgetter("message") + +template_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "templates" +) + + +async def setup_database(): + dsn = "postgresql+asyncpg://%s:%s@tfb-database:5432/hello_world" % ( + os.getenv("PGPASS", "benchmarkdbuser"), + os.getenv("PGPASS", "benchmarkdbpass"), + ) + + engine = create_async_engine( + dsn, + future=True, + pool_size=MAX_POOL_SIZE, + connect_args={ + "ssl": False # NEEDED FOR NGINX-UNIT OTHERWISE IT FAILS + }, + ) + return async_sessionmaker(engine) + + +@asynccontextmanager +async def lifespan(app: Litestar): + # Set up the database connection pool + app.state.db_session = await setup_database() + yield + # Close the database connection pool + await app.state.db_session().close() + + +app = Litestar( + template_config=TemplateConfig( + directory=Path("templates"), + engine=JinjaTemplateEngine, + ), + lifespan=[lifespan], +) + + +def get_num_queries(queries): + try: + query_count = int(queries) + except (ValueError, TypeError): + return 1 + + if query_count < 1: + return 1 + if query_count > 500: + return 500 + return query_count + + +@get("/json") +async def json_serialization(): + return ujson5.dumps({"message": "Hello, world!"}) + + +@get("/db") +async def single_database_query(): + id_ = randint(1, 10000) + + async with app.state.db_session() as sess: + result = await sess.get(World, id_) + + return ujson5.dumps(result.__json__()) + + +@get("/queries") +async def multiple_database_queries(queries=None): + num_queries = get_num_queries(queries) + data = [] + + async with app.state.db_session() as sess: + for id_ in sample(range(1, 10001), num_queries): + result = await sess.get(World, id_) + data.append(result.__json__()) + + return ujson5.dumps(data) + + +@get("/fortunes") +async def fortunes(request: Request): + async with app.state.db_session() as sess: + ret = await sess.execute(select(Fortune.id, Fortune.message)) + data = ret.all() + + data.append(ADDITIONAL_FORTUNE) + data.sort(key=sort_fortunes_key) + + return Template( + "fortune.jinja", context={"request": request, "fortunes": data} + ) + + +@get("/updates") +async def database_updates(queries=None): + num_queries = get_num_queries(queries) + + ids = sorted(sample(range(1, 10000 + 1), num_queries)) + data = [] + async with app.state.db_session.begin() as sess: + for id_ in ids: + world = await sess.get(World, id_, populate_existing=True) + world.randomnumber = randint(1, 10000) + # force sqlalchemy to UPDATE entry even if the value has not changed + # doesn't make sense in a real application, added only for pass `tfb verify` + flag_modified(world, "randomnumber") + data.append(world.__json__()) + + return ujson5.dumps(data) + + +@get("/plaintext", media_type=MediaType.TEXT) +async def plaintext(): + return b"Hello, world!" diff --git a/frameworks/Python/litestar/benchmark_config.json b/frameworks/Python/litestar/benchmark_config.json new file mode 100755 index 00000000000..9c0589cb87d --- /dev/null +++ b/frameworks/Python/litestar/benchmark_config.json @@ -0,0 +1,242 @@ +{ + "framework": "litestar", + "tests": [{ + "default": { + "json_url": "/json", + "fortune_url": "/fortunes", + "plaintext_url": "/plaintext", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Gunicorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar", + "notes": "", + "versus": "None" + }, + "socketify-asgi": { + "json_url": "/json", + "plaintext_url": "/plaintext", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Socketify.py", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar [Socketify.py ASGI]", + "notes": "", + "versus": "None" + }, + "socketify-asgi-pypy": { + "json_url": "/json", + "plaintext_url": "/plaintext", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Socketify.py", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar [Socketify.py ASGI PyPy3]", + "notes": "", + "versus": "None" + }, + "gunicorn-orjson": { + "json_url": "/json", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Gunicorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-gunicorn-orjson", + "notes": "", + "versus": "None" + }, + "gunicorn-orm": { + "fortune_url": "/fortunes", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Full", + "platform": "asyncio", + "webserver": "Gunicorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-gunicorn-orm", + "notes": "", + "versus": "None" + }, + "hypercorn": { + "json_url": "/json", + "fortune_url": "/fortunes", + "plaintext_url": "/plaintext", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Hypercorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-hypercorn", + "notes": "", + "versus": "None" + }, + "hypercorn-orjson": { + "json_url": "/json", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Hypercorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-hypercorn-orjson", + "notes": "", + "versus": "None" + }, + "nginx-unit": { + "json_url": "/json", + "fortune_url": "/fortunes", + "plaintext_url": "/plaintext", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "nginx-unit", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-nginx-unit", + "notes": "", + "versus": "None", + "tags": ["broken"] + }, + "nginx-unit-orjson": { + "json_url": "/json", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "nginx-unit", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-nginx-unit-orjson", + "notes": "", + "versus": "None", + "tags": ["broken"] + }, + "uvicorn": { + "json_url": "/json", + "fortune_url": "/fortunes", + "plaintext_url": "/plaintext", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Uvicorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-uvicorn", + "notes": "", + "versus": "None" + }, + "uvicorn-orjson": { + "json_url": "/json", + "db_url": "/db", + "query_url": "/queries?queries=", + "update_url": "/updates?queries=", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Litestar", + "language": "Python", + "flavor": "Python3", + "orm": "Raw", + "platform": "asyncio", + "webserver": "Uvicorn", + "os": "Linux", + "database_os": "Linux", + "display_name": "Litestar-uvicorn-orjson", + "notes": "", + "versus": "None" + } + }] +} diff --git a/frameworks/Python/litestar/config.toml b/frameworks/Python/litestar/config.toml new file mode 100644 index 00000000000..7f9955e83d5 --- /dev/null +++ b/frameworks/Python/litestar/config.toml @@ -0,0 +1,184 @@ +[framework] +name = "litestar" + +[gunicorn] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "Gunicorn" +versus = "None" + +[socketify-asgi-pypy] +urls.plaintext = "/plaintext" +urls.json = "/json" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "Socketify.py" +versus = "None" + +[socketify-asgi] +urls.plaintext = "/plaintext" +urls.json = "/json" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "Socketify.py" +versus = "None" + +[gunicorn-orjson] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "Gunicorn" +versus = "None" + + +[gunicorn-orm] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Full" +platform = "None" +webserver = "Gunicorn" +versus = "None" + +[hypercorn] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "Hypercorn" +versus = "None" + + +[hypercorn-orjson] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "Hypercorn" +versus = "None" + +[nginx-unit] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "nginx-unit" +versus = "None" + +[nginx-unit-orjson] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "nginx-unit" +versus = "None" + + +[uvicorn] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "uvicorn" +versus = "None" + +[uvicorn-orjson] +urls.plaintext = "/plaintext" +urls.json = "/json" +urls.db = "/db" +urls.query = "/queries?queries=" +urls.update = "/updates?queries=" +urls.fortune = "/fortunes" +approach = "Realistic" +classification = "Micro" +database = "Postgres" +database_os = "Linux" +os = "Linux" +orm = "Raw" +platform = "None" +webserver = "uvicorn" +versus = "None" diff --git a/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile new file mode 100644 index 00000000000..7ecb52de369 --- /dev/null +++ b/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-orjson.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-orjson.txt -r requirements-gunicorn.txt -r requirements-uvicorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD gunicorn app:app -k uvicorn.workers.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile new file mode 100644 index 00000000000..e1d74c680d8 --- /dev/null +++ b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile @@ -0,0 +1,20 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-sqlalchemy.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-sqlalchemy.txt -r requirements-gunicorn.txt -r requirements-uvicorn.txt + +COPY . ./ + +EXPOSE 8080 + +ENV CONNECTION=ORM + +CMD gunicorn app_orm:app -k uvicorn.workers.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile new file mode 100644 index 00000000000..fc50bd7ddae --- /dev/null +++ b/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-orjson.txt requirements-hypercorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-orjson.txt -r requirements-hypercorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD hypercorn app:app --bind 0.0.0.0:8080 --workers $(nproc) diff --git a/frameworks/Python/litestar/litestar-hypercorn.dockerfile b/frameworks/Python/litestar/litestar-hypercorn.dockerfile new file mode 100644 index 00000000000..58f2d166d12 --- /dev/null +++ b/frameworks/Python/litestar/litestar-hypercorn.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-hypercorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-hypercorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD hypercorn app:app --bind 0.0.0.0:8080 --workers $(nproc) diff --git a/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile b/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile new file mode 100644 index 00000000000..af3ed2bd75d --- /dev/null +++ b/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile @@ -0,0 +1,20 @@ +FROM nginx/unit:1.29.1-python3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-orjson.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-orjson.txt + +COPY . ./ + +COPY ./nginx-unit-config-orjson.sh /docker-entrypoint.d/ + +ENV PGSSLMODE disable + +EXPOSE 8080 diff --git a/frameworks/Python/litestar/litestar-nginx-unit.dockerfile b/frameworks/Python/litestar/litestar-nginx-unit.dockerfile new file mode 100644 index 00000000000..261c84d5520 --- /dev/null +++ b/frameworks/Python/litestar/litestar-nginx-unit.dockerfile @@ -0,0 +1,20 @@ +FROM nginx/unit:1.29.1-python3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt ./ + +RUN pip3 install -r requirements.txt + +COPY . ./ + +COPY ./nginx-unit-config.sh /docker-entrypoint.d/ + +ENV PGSSLMODE disable + +EXPOSE 8080 diff --git a/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile b/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile new file mode 100644 index 00000000000..39a7e0c5b05 --- /dev/null +++ b/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile @@ -0,0 +1,16 @@ +FROM pypy:3.11-bookworm + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +COPY requirements-socketify-pypy.txt ./ +RUN apt-get update; apt-get install libuv1 -y +RUN pip3 install -r requirements-socketify-pypy.txt + +COPY . ./ + +EXPOSE 8080 + +CMD python ./app-socketify-asgi.py diff --git a/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile b/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile new file mode 100644 index 00000000000..58c39a397cd --- /dev/null +++ b/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile @@ -0,0 +1,19 @@ +FROM python:3.13-bullseye + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN apt-get update; apt-get install libuv1 -y +RUN pip3 install cython==3.0.12 + +COPY requirements-socketify.txt ./ + +RUN pip3 install -r requirements-socketify.txt + +COPY . ./ + +EXPOSE 8080 + +CMD python ./app-socketify-asgi.py diff --git a/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile new file mode 100644 index 00000000000..35e6b7d0030 --- /dev/null +++ b/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-orjson.txt requirements-uvicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-orjson.txt -r requirements-uvicorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD uvicorn app:app --host 0.0.0.0 --port 8080 --workers $(nproc) --log-level error diff --git a/frameworks/Python/litestar/litestar-uvicorn.dockerfile b/frameworks/Python/litestar/litestar-uvicorn.dockerfile new file mode 100644 index 00000000000..7da0ea40ce3 --- /dev/null +++ b/frameworks/Python/litestar/litestar-uvicorn.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-uvicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-uvicorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD uvicorn app:app --host 0.0.0.0 --port 8080 --workers $(nproc) --log-level error diff --git a/frameworks/Python/litestar/litestar.dockerfile b/frameworks/Python/litestar/litestar.dockerfile new file mode 100644 index 00000000000..2cc2d5f2afd --- /dev/null +++ b/frameworks/Python/litestar/litestar.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /fastapi + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-gunicorn.txt -r requirements-uvicorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD gunicorn app:app -k uvicorn.workers.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar_conf.py b/frameworks/Python/litestar/litestar_conf.py new file mode 100644 index 00000000000..6f6aec65f89 --- /dev/null +++ b/frameworks/Python/litestar/litestar_conf.py @@ -0,0 +1,12 @@ +import multiprocessing +import os + +_is_travis = os.environ.get('TRAVIS') == 'true' + +workers = multiprocessing.cpu_count() + +bind = "0.0.0.0:8080" +keepalive = 120 +errorlog = '-' +pidfile = '/tmp/litestar.pid' +loglevel = 'error' diff --git a/frameworks/Python/litestar/nginx-unit-config-orjson.sh b/frameworks/Python/litestar/nginx-unit-config-orjson.sh new file mode 100755 index 00000000000..3f947f13a90 --- /dev/null +++ b/frameworks/Python/litestar/nginx-unit-config-orjson.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +config='{' +config+=' "listeners": {' +config+=' "*:8080": {' +config+=' "pass": "applications/litestar"' +config+=' }' +config+=' },' +config+=' "applications": {' +config+=' "litestar": {' +config+=' "type": "python",' +config+=' "path": "/litestar",' +config+=' "home": "/opt/venv/",' +config+=' "protocol": "asgi",' +config+=' "module": "app",' +config+=' "callable": "app",' +config+=' "processes": '"$(nproc)"',' +config+=' }' +config+=' }', +config+=' "access_log": "/dev/null"' +config+='}' + +curl -X PUT \ + --data-binary "$config" \ + --unix-socket /var/run/control.unit.sock \ + http://localhost/config diff --git a/frameworks/Python/litestar/nginx-unit-config.sh b/frameworks/Python/litestar/nginx-unit-config.sh new file mode 100755 index 00000000000..3f947f13a90 --- /dev/null +++ b/frameworks/Python/litestar/nginx-unit-config.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +config='{' +config+=' "listeners": {' +config+=' "*:8080": {' +config+=' "pass": "applications/litestar"' +config+=' }' +config+=' },' +config+=' "applications": {' +config+=' "litestar": {' +config+=' "type": "python",' +config+=' "path": "/litestar",' +config+=' "home": "/opt/venv/",' +config+=' "protocol": "asgi",' +config+=' "module": "app",' +config+=' "callable": "app",' +config+=' "processes": '"$(nproc)"',' +config+=' }' +config+=' }', +config+=' "access_log": "/dev/null"' +config+='}' + +curl -X PUT \ + --data-binary "$config" \ + --unix-socket /var/run/control.unit.sock \ + http://localhost/config diff --git a/frameworks/Python/litestar/requirements-gunicorn.txt b/frameworks/Python/litestar/requirements-gunicorn.txt new file mode 100644 index 00000000000..4afe40e70ce --- /dev/null +++ b/frameworks/Python/litestar/requirements-gunicorn.txt @@ -0,0 +1 @@ +gunicorn==23.0.0 diff --git a/frameworks/Python/litestar/requirements-hypercorn.txt b/frameworks/Python/litestar/requirements-hypercorn.txt new file mode 100644 index 00000000000..3e0a21f2fe2 --- /dev/null +++ b/frameworks/Python/litestar/requirements-hypercorn.txt @@ -0,0 +1 @@ +hypercorn==0.17.3 diff --git a/frameworks/Python/litestar/requirements-orjson.txt b/frameworks/Python/litestar/requirements-orjson.txt new file mode 100644 index 00000000000..e170985be34 --- /dev/null +++ b/frameworks/Python/litestar/requirements-orjson.txt @@ -0,0 +1 @@ +orjson==3.10.18 diff --git a/frameworks/Python/litestar/requirements-socketify-pypy.txt b/frameworks/Python/litestar/requirements-socketify-pypy.txt new file mode 100644 index 00000000000..393fdeebfca --- /dev/null +++ b/frameworks/Python/litestar/requirements-socketify-pypy.txt @@ -0,0 +1,2 @@ +litestar==2.16.0 +git+https://github.com/cirospaciari/socketify.py.git@main#socketify diff --git a/frameworks/Python/litestar/requirements-socketify.txt b/frameworks/Python/litestar/requirements-socketify.txt new file mode 100644 index 00000000000..70c19fabec9 --- /dev/null +++ b/frameworks/Python/litestar/requirements-socketify.txt @@ -0,0 +1,3 @@ +orjson==3.10.16 +litestar==2.16.0 +git+https://github.com/cirospaciari/socketify.py.git@main#socketify diff --git a/frameworks/Python/litestar/requirements-sqlalchemy.txt b/frameworks/Python/litestar/requirements-sqlalchemy.txt new file mode 100644 index 00000000000..d2e7a36be45 --- /dev/null +++ b/frameworks/Python/litestar/requirements-sqlalchemy.txt @@ -0,0 +1,3 @@ +psycopg2==2.9.10 +SQLAlchemy==2.0.40 +litestar[sqlalchemy]==2.16.0 \ No newline at end of file diff --git a/frameworks/Python/litestar/requirements-uvicorn.txt b/frameworks/Python/litestar/requirements-uvicorn.txt new file mode 100644 index 00000000000..e9603a4a89c --- /dev/null +++ b/frameworks/Python/litestar/requirements-uvicorn.txt @@ -0,0 +1,3 @@ +uvicorn==0.34.2 +uvloop==0.21.0 +httptools==0.6.4 diff --git a/frameworks/Python/litestar/requirements.txt b/frameworks/Python/litestar/requirements.txt new file mode 100644 index 00000000000..565e9b20530 --- /dev/null +++ b/frameworks/Python/litestar/requirements.txt @@ -0,0 +1,4 @@ +asyncpg==0.30.0 +litestar==2.16.0 +Jinja2==3.1.6 +ujson5==1.0.1 \ No newline at end of file diff --git a/frameworks/Python/litestar/templates/fortune.html b/frameworks/Python/litestar/templates/fortune.html new file mode 100644 index 00000000000..1c90834285d --- /dev/null +++ b/frameworks/Python/litestar/templates/fortune.html @@ -0,0 +1,10 @@ + + +Fortunes + + + +{% for fortune in fortunes %} +{% endfor %}
idmessage
{{ fortune[0] }}{{ fortune[1]|e }}
+ + diff --git a/frameworks/Python/litestar/templates/fortune.jinja b/frameworks/Python/litestar/templates/fortune.jinja new file mode 100644 index 00000000000..5126edffbf7 --- /dev/null +++ b/frameworks/Python/litestar/templates/fortune.jinja @@ -0,0 +1,10 @@ + + +Fortunes + + + +{% for fortune in fortunes %} +{% endfor %}
idmessage
{{ fortune.id }}{{ fortune.message|e }}
+ + From e16dc6c912c00568757f87469c7c36c03c987e83 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Mon, 19 May 2025 16:07:57 +0530 Subject: [PATCH 02/15] feat: add support for litestar --- frameworks/Python/litestar/README.md | 2 +- frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile | 2 +- frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile | 2 +- frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile | 2 +- frameworks/Python/litestar/litestar-hypercorn.dockerfile | 2 +- .../Python/litestar/litestar-nginx-unit-orjson.dockerfile | 2 +- frameworks/Python/litestar/litestar-nginx-unit.dockerfile | 2 +- .../Python/litestar/litestar-socketify-asgi-pypy.dockerfile | 2 +- frameworks/Python/litestar/litestar-socketify-asgi.dockerfile | 2 +- frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile | 2 +- frameworks/Python/litestar/litestar-uvicorn.dockerfile | 2 +- frameworks/Python/litestar/litestar.dockerfile | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/frameworks/Python/litestar/README.md b/frameworks/Python/litestar/README.md index f61cec947c7..c4b2b3e7ec8 100755 --- a/frameworks/Python/litestar/README.md +++ b/frameworks/Python/litestar/README.md @@ -10,7 +10,7 @@ the [Python README](../). ## Description -[**Litestar**](https://github.com/tiangolo/fastapi) is a modern, fast (high-performance), web framework for building APIs with Python 3.6+. +[**Litestar**](https://github.com/litestar-org/litestar) is a modern, fast (high-performance), web framework for building APIs with Python 3.6+. The key features are: diff --git a/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile index 7ecb52de369..6d7f67aa008 100644 --- a/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile +++ b/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile index e1d74c680d8..021ba86de5f 100644 --- a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile +++ b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile index fc50bd7ddae..bd89b36870e 100644 --- a/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile +++ b/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-hypercorn.dockerfile b/frameworks/Python/litestar/litestar-hypercorn.dockerfile index 58f2d166d12..aede52755fc 100644 --- a/frameworks/Python/litestar/litestar-hypercorn.dockerfile +++ b/frameworks/Python/litestar/litestar-hypercorn.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile b/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile index af3ed2bd75d..e120a14d225 100644 --- a/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile +++ b/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile @@ -1,6 +1,6 @@ FROM nginx/unit:1.29.1-python3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-nginx-unit.dockerfile b/frameworks/Python/litestar/litestar-nginx-unit.dockerfile index 261c84d5520..b7b60b6f3d9 100644 --- a/frameworks/Python/litestar/litestar-nginx-unit.dockerfile +++ b/frameworks/Python/litestar/litestar-nginx-unit.dockerfile @@ -1,6 +1,6 @@ FROM nginx/unit:1.29.1-python3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile b/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile index 39a7e0c5b05..6a778fdc075 100644 --- a/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile +++ b/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile @@ -1,6 +1,6 @@ FROM pypy:3.11-bookworm -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile b/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile index 58c39a397cd..0233ec1aebf 100644 --- a/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile +++ b/frameworks/Python/litestar/litestar-socketify-asgi.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13-bullseye -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile index 35e6b7d0030..c47267f1a3d 100644 --- a/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile +++ b/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar-uvicorn.dockerfile b/frameworks/Python/litestar/litestar-uvicorn.dockerfile index 7da0ea40ce3..bacb4961ba1 100644 --- a/frameworks/Python/litestar/litestar-uvicorn.dockerfile +++ b/frameworks/Python/litestar/litestar-uvicorn.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" diff --git a/frameworks/Python/litestar/litestar.dockerfile b/frameworks/Python/litestar/litestar.dockerfile index 2cc2d5f2afd..717f3ec65d8 100644 --- a/frameworks/Python/litestar/litestar.dockerfile +++ b/frameworks/Python/litestar/litestar.dockerfile @@ -1,6 +1,6 @@ FROM python:3.13 -WORKDIR /fastapi +WORKDIR /litestar RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" From 70172fb56d128d9131f9fe1de53834c15b88f458 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 13:19:26 +0530 Subject: [PATCH 03/15] feat: refactor app structure and update dependencies --- ...dockerfile => litestar-granian.dockerfile} | 2 +- .../litestar-gunicorn-orjson.dockerfile | 18 ----------------- .../litestar-hypercorn-orjson.dockerfile | 18 ----------------- .../litestar-nginx-unit-orjson.dockerfile | 20 ------------------- .../litestar-uvicorn-orjson.dockerfile | 18 ----------------- ...hypercorn.txt => requirements-granian.txt} | 0 .../Python/litestar/requirements-orjson.txt | 1 - 7 files changed, 1 insertion(+), 76 deletions(-) rename frameworks/Python/litestar/{litestar-hypercorn.dockerfile => litestar-granian.dockerfile} (80%) delete mode 100644 frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile delete mode 100644 frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile delete mode 100644 frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile delete mode 100644 frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile rename frameworks/Python/litestar/{requirements-hypercorn.txt => requirements-granian.txt} (100%) delete mode 100644 frameworks/Python/litestar/requirements-orjson.txt diff --git a/frameworks/Python/litestar/litestar-hypercorn.dockerfile b/frameworks/Python/litestar/litestar-granian.dockerfile similarity index 80% rename from frameworks/Python/litestar/litestar-hypercorn.dockerfile rename to frameworks/Python/litestar/litestar-granian.dockerfile index aede52755fc..f82323ec1d3 100644 --- a/frameworks/Python/litestar/litestar-hypercorn.dockerfile +++ b/frameworks/Python/litestar/litestar-granian.dockerfile @@ -9,7 +9,7 @@ RUN pip3 install cython==3.0.12 COPY requirements.txt requirements-hypercorn.txt ./ -RUN pip3 install -r requirements.txt -r requirements-hypercorn.txt +RUN pip3 install -r requirements.txt -r requirements-granian.txt COPY . ./ diff --git a/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile deleted file mode 100644 index 6d7f67aa008..00000000000 --- a/frameworks/Python/litestar/litestar-gunicorn-orjson.dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM python:3.13 - -WORKDIR /litestar - -RUN python -m venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" - -RUN pip3 install cython==3.0.12 - -COPY requirements.txt requirements-orjson.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ - -RUN pip3 install -r requirements.txt -r requirements-orjson.txt -r requirements-gunicorn.txt -r requirements-uvicorn.txt - -COPY . ./ - -EXPOSE 8080 - -CMD gunicorn app:app -k uvicorn.workers.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile deleted file mode 100644 index bd89b36870e..00000000000 --- a/frameworks/Python/litestar/litestar-hypercorn-orjson.dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM python:3.13 - -WORKDIR /litestar - -RUN python -m venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" - -RUN pip3 install cython==3.0.12 - -COPY requirements.txt requirements-orjson.txt requirements-hypercorn.txt ./ - -RUN pip3 install -r requirements.txt -r requirements-orjson.txt -r requirements-hypercorn.txt - -COPY . ./ - -EXPOSE 8080 - -CMD hypercorn app:app --bind 0.0.0.0:8080 --workers $(nproc) diff --git a/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile b/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile deleted file mode 100644 index e120a14d225..00000000000 --- a/frameworks/Python/litestar/litestar-nginx-unit-orjson.dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM nginx/unit:1.29.1-python3.13 - -WORKDIR /litestar - -RUN python -m venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" - -RUN pip3 install cython==3.0.12 - -COPY requirements.txt requirements-orjson.txt ./ - -RUN pip3 install -r requirements.txt -r requirements-orjson.txt - -COPY . ./ - -COPY ./nginx-unit-config-orjson.sh /docker-entrypoint.d/ - -ENV PGSSLMODE disable - -EXPOSE 8080 diff --git a/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile b/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile deleted file mode 100644 index c47267f1a3d..00000000000 --- a/frameworks/Python/litestar/litestar-uvicorn-orjson.dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM python:3.13 - -WORKDIR /litestar - -RUN python -m venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" - -RUN pip3 install cython==3.0.12 - -COPY requirements.txt requirements-orjson.txt requirements-uvicorn.txt ./ - -RUN pip3 install -r requirements.txt -r requirements-orjson.txt -r requirements-uvicorn.txt - -COPY . ./ - -EXPOSE 8080 - -CMD uvicorn app:app --host 0.0.0.0 --port 8080 --workers $(nproc) --log-level error diff --git a/frameworks/Python/litestar/requirements-hypercorn.txt b/frameworks/Python/litestar/requirements-granian.txt similarity index 100% rename from frameworks/Python/litestar/requirements-hypercorn.txt rename to frameworks/Python/litestar/requirements-granian.txt diff --git a/frameworks/Python/litestar/requirements-orjson.txt b/frameworks/Python/litestar/requirements-orjson.txt deleted file mode 100644 index e170985be34..00000000000 --- a/frameworks/Python/litestar/requirements-orjson.txt +++ /dev/null @@ -1 +0,0 @@ -orjson==3.10.18 From 39b5384c98a72db3f15edb9ebdceade1b8c94d14 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 13:20:04 +0530 Subject: [PATCH 04/15] feat: update app structure and replace ujson5 with orjson --- .../litestar/__pycache__/app.cpython-312.pyc | Bin 0 -> 7694 bytes .../__pycache__/app_orm.cpython-312.pyc | Bin 0 -> 8633 bytes .../Python/litestar/app-socketify-asgi.py | 33 +-- frameworks/Python/litestar/app.py | 160 ++++++++------- frameworks/Python/litestar/app_orm.py | 192 +++++++++--------- .../litestar/litestar-granian.dockerfile | 2 +- .../litestar/litestar-gunicorn-orm.dockerfile | 2 +- .../Python/litestar/litestar.dockerfile | 2 +- frameworks/Python/litestar/litestar_conf.py | 8 +- .../Python/litestar/requirements-granian.txt | 3 +- .../Python/litestar/requirements-gunicorn.txt | 1 + frameworks/Python/litestar/requirements.txt | 2 +- frameworks/Python/litestar/ruff.toml | 79 +++++++ 13 files changed, 290 insertions(+), 194 deletions(-) create mode 100644 frameworks/Python/litestar/__pycache__/app.cpython-312.pyc create mode 100644 frameworks/Python/litestar/__pycache__/app_orm.cpython-312.pyc create mode 100644 frameworks/Python/litestar/ruff.toml diff --git a/frameworks/Python/litestar/__pycache__/app.cpython-312.pyc b/frameworks/Python/litestar/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41edeed61781c621f71e9de77474b15f63a11973 GIT binary patch literal 7694 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 0: - run_app() + n = os.fork() + # n greater than 0 means parent process + if not n > 0: + run_app() # fork limiting the cpu count - 1 for i in range(1, workers): - create_fork() + create_fork() -run_app() # run app on the main process too :) \ No newline at end of file +run_app() # run app on the main process too :) diff --git a/frameworks/Python/litestar/app.py b/frameworks/Python/litestar/app.py index d93507623b3..67df2ea4f89 100755 --- a/frameworks/Python/litestar/app.py +++ b/frameworks/Python/litestar/app.py @@ -1,15 +1,13 @@ import multiprocessing +import os from contextlib import asynccontextmanager from pathlib import Path +from random import randint, sample +from typing import Any import asyncpg -import os - import orjson -from litestar import Litestar, Request, get, MediaType - -from random import randint, sample - +from litestar import Litestar, MediaType, Request, get from litestar.contrib.jinja import JinjaTemplateEngine from litestar.response import Template from litestar.template import TemplateConfig @@ -17,114 +15,122 @@ READ_ROW_SQL = 'SELECT "id", "randomnumber" FROM "world" WHERE id = $1' WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2' ADDITIONAL_ROW = [0, "Additional fortune added at request time."] -MAX_POOL_SIZE = 1000//multiprocessing.cpu_count() +MAX_POOL_SIZE = 1000 // multiprocessing.cpu_count() MIN_POOL_SIZE = max(int(MAX_POOL_SIZE / 2), 1) def get_num_queries(queries): - try: - query_count = int(queries) - except (ValueError, TypeError): - return 1 + try: + query_count = int(queries) + except (ValueError, TypeError): + return 1 - if query_count < 1: - return 1 - if query_count > 500: - return 500 - return query_count + if query_count < 1: + return 1 + if query_count > 500: + return 500 + return query_count connection_pool = None - async def setup_database(): - return await asyncpg.create_pool( - user=os.getenv("PGUSER", "benchmarkdbuser"), - password=os.getenv("PGPASS", "benchmarkdbpass"), - database="hello_world", - host="tfb-database", - port=5432, - min_size=MIN_POOL_SIZE, - max_size=MAX_POOL_SIZE, - ) + return await asyncpg.create_pool( + user=os.getenv("PGUSER", "benchmarkdbuser"), + password=os.getenv("PGPASS", "benchmarkdbpass"), + database="hello_world", + host="tfb-database", + port=5432, + min_size=MIN_POOL_SIZE, + max_size=MAX_POOL_SIZE, + ) @asynccontextmanager async def lifespan(app: Litestar): - # Set up the database connection pool - app.state.connection_pool = await setup_database() - yield - # Close the database connection pool - await app.state.connection_pool.close() - - -app = Litestar(lifespan=[lifespan], template_config=TemplateConfig( - directory=Path("templates"), - engine=JinjaTemplateEngine, - ),) + # Set up the database connection pool + app.state.connection_pool = await setup_database() + yield + # Close the database connection pool + await app.state.connection_pool.close() @get("/json") -async def json_serialization(): - return orjson.dumps({"message": "Hello, world!"}) +async def json_serialization() -> bytes: + return orjson.dumps({"message": "Hello, world!"}) @get("/db") -async def single_database_query(): - row_id = randint(1, 10000) - async with app.state.connection_pool.acquire() as connection: - number = await connection.fetchval(READ_ROW_SQL, row_id) +async def single_database_query() -> bytes: + row_id = randint(1, 10000) + async with app.state.connection_pool.acquire() as connection: + number = await connection.fetchval(READ_ROW_SQL, row_id) - return orjson.dumps({"id": row_id, "randomNumber": number}) + return orjson.dumps({"id": row_id, "randomNumber": number}) @get("/queries") -async def multiple_database_queries(queries = None): - num_queries = get_num_queries(queries) - row_ids = sample(range(1, 10000), num_queries) - worlds = [] +async def multiple_database_queries(queries: Any = None) -> bytes: + num_queries = get_num_queries(queries) + row_ids = sample(range(1, 10000), num_queries) + worlds = [] - async with app.state.connection_pool.acquire() as connection: - statement = await connection.prepare(READ_ROW_SQL) - for row_id in row_ids: - number = await statement.fetchval(row_id) - worlds.append({"id": row_id, "randomNumber": number}) + async with app.state.connection_pool.acquire() as connection: + statement = await connection.prepare(READ_ROW_SQL) + for row_id in row_ids: + number = await statement.fetchval(row_id) + worlds.append({"id": row_id, "randomNumber": number}) - return orjson.dumps(worlds) + return orjson.dumps(worlds) @get("/fortunes") -async def fortunes(request: Request): - async with app.state.connection_pool.acquire() as connection: - fortunes = await connection.fetch("SELECT * FROM Fortune") +async def fortunes(request: Request) -> Template: + async with app.state.connection_pool.acquire() as connection: + fortunes = await connection.fetch("SELECT * FROM Fortune") - fortunes.append(ADDITIONAL_ROW) - fortunes.sort(key=lambda row: row[1]) - return Template("fortune.html", context={"fortunes": fortunes, "request": request}) + fortunes.append(ADDITIONAL_ROW) + fortunes.sort(key=lambda row: row[1]) + return Template("fortune.html", context={"fortunes": fortunes, "request": request}) @get("/updates") -async def database_updates(queries = None): - num_queries = get_num_queries(queries) - # To avoid deadlock - ids = sorted(sample(range(1, 10000 + 1), num_queries)) - numbers = sorted(sample(range(1, 10000), num_queries)) - updates = list(zip(ids, numbers)) +async def database_updates(queries: Any = None) -> bytes: + num_queries = get_num_queries(queries) + # To avoid deadlock + ids = sorted(sample(range(1, 10000 + 1), num_queries)) + numbers = sorted(sample(range(1, 10000), num_queries)) + updates = list(zip(ids, numbers, strict=False)) - worlds = [ - {"id": row_id, "randomNumber": number} for row_id, number in updates - ] + worlds = [{"id": row_id, "randomNumber": number} for row_id, number in updates] - async with app.state.connection_pool.acquire() as connection: - statement = await connection.prepare(READ_ROW_SQL) - for row_id, _ in updates: - await statement.fetchval(row_id) - await connection.executemany(WRITE_ROW_SQL, updates) + async with app.state.connection_pool.acquire() as connection: + statement = await connection.prepare(READ_ROW_SQL) + for row_id, _ in updates: + await statement.fetchval(row_id) + await connection.executemany(WRITE_ROW_SQL, updates) - return orjson.dumps(worlds) + return orjson.dumps(worlds) @get("/plaintext", media_type=MediaType.TEXT) -async def plaintext(): - return b"Hello, world!" +async def plaintext() -> bytes: + return b"Hello, world!" + + +app = Litestar( + lifespan=[lifespan], + template_config=TemplateConfig( + directory=Path("templates"), + engine=JinjaTemplateEngine, + ), + route_handlers=[ + json_serialization, + single_database_query, + multiple_database_queries, + fortunes, + database_updates, + plaintext, + ], +) diff --git a/frameworks/Python/litestar/app_orm.py b/frameworks/Python/litestar/app_orm.py index 27b8cc9c301..74d4c9ef1db 100755 --- a/frameworks/Python/litestar/app_orm.py +++ b/frameworks/Python/litestar/app_orm.py @@ -5,163 +5,165 @@ from operator import attrgetter from pathlib import Path from random import randint, sample +from typing import Any -import ujson5 +import orjson +from litestar import Litestar, MediaType, Request, get from litestar.contrib.jinja import JinjaTemplateEngine from litestar.response import Template from litestar.template import TemplateConfig from sqlalchemy import Column, Integer, String, select -from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker +from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm.attributes import flag_modified -from litestar import Litestar, Request, MediaType, get - logger = logging.getLogger(__name__) Base = declarative_base() class World(Base): - __tablename__ = "world" - id = Column(Integer, primary_key=True) - randomnumber = Column(Integer) + __tablename__ = "world" + id = Column(Integer, primary_key=True) + randomnumber = Column(Integer) - def __json__(self): - return {"id": self.id, "randomnumber": self.randomnumber} + def __json__(self): + return {"id": self.id, "randomnumber": self.randomnumber} sa_data = World.__table__ class Fortune(Base): - __tablename__ = "fortune" - id = Column(Integer, primary_key=True) - message = Column(String) + __tablename__ = "fortune" + id = Column(Integer, primary_key=True) + message = Column(String) sa_fortunes = Fortune.__table__ -ADDITIONAL_FORTUNE = Fortune( - id=0, message="Additional fortune added at request time." -) -MAX_POOL_SIZE = 1000//multiprocessing.cpu_count() +ADDITIONAL_FORTUNE = Fortune(id=0, message="Additional fortune added at request time.") +MAX_POOL_SIZE = 1000 // multiprocessing.cpu_count() sort_fortunes_key = attrgetter("message") -template_path = os.path.join( - os.path.dirname(os.path.realpath(__file__)), "templates" -) +template_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") async def setup_database(): - dsn = "postgresql+asyncpg://%s:%s@tfb-database:5432/hello_world" % ( - os.getenv("PGPASS", "benchmarkdbuser"), - os.getenv("PGPASS", "benchmarkdbpass"), - ) - - engine = create_async_engine( - dsn, - future=True, - pool_size=MAX_POOL_SIZE, - connect_args={ - "ssl": False # NEEDED FOR NGINX-UNIT OTHERWISE IT FAILS - }, - ) - return async_sessionmaker(engine) + dsn = "postgresql+asyncpg://%s:%s@tfb-database:5432/hello_world" % ( + os.getenv("PGPASS", "benchmarkdbuser"), + os.getenv("PGPASS", "benchmarkdbpass"), + ) + + engine = create_async_engine( + dsn, + future=True, + pool_size=MAX_POOL_SIZE, + connect_args={ + "ssl": False # NEEDED FOR NGINX-UNIT OTHERWISE IT FAILS + }, + ) + return async_sessionmaker(engine) @asynccontextmanager async def lifespan(app: Litestar): - # Set up the database connection pool - app.state.db_session = await setup_database() - yield - # Close the database connection pool - await app.state.db_session().close() - - -app = Litestar( - template_config=TemplateConfig( - directory=Path("templates"), - engine=JinjaTemplateEngine, - ), - lifespan=[lifespan], -) + # Set up the database connection pool + app.state.db_session = await setup_database() + yield + # Close the database connection pool + await app.state.db_session().close() def get_num_queries(queries): - try: - query_count = int(queries) - except (ValueError, TypeError): - return 1 + try: + query_count = int(queries) + except (ValueError, TypeError): + return 1 - if query_count < 1: - return 1 - if query_count > 500: - return 500 - return query_count + if query_count < 1: + return 1 + if query_count > 500: + return 500 + return query_count @get("/json") -async def json_serialization(): - return ujson5.dumps({"message": "Hello, world!"}) +async def json_serialization() -> bytes: + return orjson.dumps({"message": "Hello, world!"}) @get("/db") -async def single_database_query(): - id_ = randint(1, 10000) +async def single_database_query() -> bytes: + id_ = randint(1, 10000) - async with app.state.db_session() as sess: - result = await sess.get(World, id_) + async with app.state.db_session() as sess: + result = await sess.get(World, id_) - return ujson5.dumps(result.__json__()) + return orjson.dumps(result.__json__()) @get("/queries") -async def multiple_database_queries(queries=None): - num_queries = get_num_queries(queries) - data = [] +async def multiple_database_queries(queries: Any = None) -> bytes: + num_queries = get_num_queries(queries) + data = [] - async with app.state.db_session() as sess: - for id_ in sample(range(1, 10001), num_queries): - result = await sess.get(World, id_) - data.append(result.__json__()) + async with app.state.db_session() as sess: + for id_ in sample(range(1, 10001), num_queries): + result = await sess.get(World, id_) + data.append(result.__json__()) - return ujson5.dumps(data) + return orjson.dumps(data) @get("/fortunes") -async def fortunes(request: Request): - async with app.state.db_session() as sess: - ret = await sess.execute(select(Fortune.id, Fortune.message)) - data = ret.all() +async def fortunes(request: Request) -> Template: + async with app.state.db_session() as sess: + ret = await sess.execute(select(Fortune.id, Fortune.message)) + data = ret.all() - data.append(ADDITIONAL_FORTUNE) - data.sort(key=sort_fortunes_key) + data.append(ADDITIONAL_FORTUNE) + data.sort(key=sort_fortunes_key) - return Template( - "fortune.jinja", context={"request": request, "fortunes": data} - ) + return Template("fortune.jinja", context={"request": request, "fortunes": data}) @get("/updates") -async def database_updates(queries=None): - num_queries = get_num_queries(queries) +async def database_updates(queries: Any = None) -> bytes: + num_queries = get_num_queries(queries) - ids = sorted(sample(range(1, 10000 + 1), num_queries)) - data = [] - async with app.state.db_session.begin() as sess: - for id_ in ids: - world = await sess.get(World, id_, populate_existing=True) - world.randomnumber = randint(1, 10000) - # force sqlalchemy to UPDATE entry even if the value has not changed - # doesn't make sense in a real application, added only for pass `tfb verify` - flag_modified(world, "randomnumber") - data.append(world.__json__()) + ids = sorted(sample(range(1, 10000 + 1), num_queries)) + data = [] + async with app.state.db_session.begin() as sess: + for id_ in ids: + world = await sess.get(World, id_, populate_existing=True) + world.randomnumber = randint(1, 10000) + # force sqlalchemy to UPDATE entry even if the value has not changed + # doesn't make sense in a real application, added only for pass `tfb verify` + flag_modified(world, "randomnumber") + data.append(world.__json__()) - return ujson5.dumps(data) + return orjson.dumps(data) @get("/plaintext", media_type=MediaType.TEXT) -async def plaintext(): - return b"Hello, world!" +async def plaintext() -> bytes: + return b"Hello, world!" + + +app = Litestar( + template_config=TemplateConfig( + directory=Path("templates"), + engine=JinjaTemplateEngine, + ), + lifespan=[lifespan], + route_handlers=[ + json_serialization, + single_database_query, + multiple_database_queries, + fortunes, + database_updates, + plaintext, + ], +) diff --git a/frameworks/Python/litestar/litestar-granian.dockerfile b/frameworks/Python/litestar/litestar-granian.dockerfile index f82323ec1d3..f44571fb483 100644 --- a/frameworks/Python/litestar/litestar-granian.dockerfile +++ b/frameworks/Python/litestar/litestar-granian.dockerfile @@ -15,4 +15,4 @@ COPY . ./ EXPOSE 8080 -CMD hypercorn app:app --bind 0.0.0.0:8080 --workers $(nproc) +CMD granian --interface asgi app:app --host '0.0.0.0' --port 8080 --workers $(nproc) --http 2 diff --git a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile index 021ba86de5f..e5b0bedecb0 100644 --- a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile +++ b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile @@ -17,4 +17,4 @@ EXPOSE 8080 ENV CONNECTION=ORM -CMD gunicorn app_orm:app -k uvicorn.workers.UvicornWorker -c litestar_conf.py +CMD gunicorn app_orm:app -k uvicorn_worker.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar.dockerfile b/frameworks/Python/litestar/litestar.dockerfile index 717f3ec65d8..1df7f8b4d7e 100644 --- a/frameworks/Python/litestar/litestar.dockerfile +++ b/frameworks/Python/litestar/litestar.dockerfile @@ -15,4 +15,4 @@ COPY . ./ EXPOSE 8080 -CMD gunicorn app:app -k uvicorn.workers.UvicornWorker -c litestar_conf.py +CMD gunicorn app:app -k uvicorn_worker.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar_conf.py b/frameworks/Python/litestar/litestar_conf.py index 6f6aec65f89..c0f0af8f743 100644 --- a/frameworks/Python/litestar/litestar_conf.py +++ b/frameworks/Python/litestar/litestar_conf.py @@ -1,12 +1,12 @@ import multiprocessing import os -_is_travis = os.environ.get('TRAVIS') == 'true' +_is_travis = os.environ.get("TRAVIS") == "true" workers = multiprocessing.cpu_count() bind = "0.0.0.0:8080" keepalive = 120 -errorlog = '-' -pidfile = '/tmp/litestar.pid' -loglevel = 'error' +errorlog = "-" +pidfile = "/tmp/litestar.pid" +loglevel = "error" diff --git a/frameworks/Python/litestar/requirements-granian.txt b/frameworks/Python/litestar/requirements-granian.txt index 3e0a21f2fe2..946bfa8d0b1 100644 --- a/frameworks/Python/litestar/requirements-granian.txt +++ b/frameworks/Python/litestar/requirements-granian.txt @@ -1 +1,2 @@ -hypercorn==0.17.3 +granian==2.3.1 +litestar-granian==0.13.0 \ No newline at end of file diff --git a/frameworks/Python/litestar/requirements-gunicorn.txt b/frameworks/Python/litestar/requirements-gunicorn.txt index 4afe40e70ce..c95d2c0209a 100644 --- a/frameworks/Python/litestar/requirements-gunicorn.txt +++ b/frameworks/Python/litestar/requirements-gunicorn.txt @@ -1 +1,2 @@ gunicorn==23.0.0 +uvicorn-worker==0.3.0 diff --git a/frameworks/Python/litestar/requirements.txt b/frameworks/Python/litestar/requirements.txt index 565e9b20530..e2b341ae256 100644 --- a/frameworks/Python/litestar/requirements.txt +++ b/frameworks/Python/litestar/requirements.txt @@ -1,4 +1,4 @@ asyncpg==0.30.0 litestar==2.16.0 Jinja2==3.1.6 -ujson5==1.0.1 \ No newline at end of file +orjson==3.10.18 \ No newline at end of file diff --git a/frameworks/Python/litestar/ruff.toml b/frameworks/Python/litestar/ruff.toml new file mode 100644 index 00000000000..adaca462881 --- /dev/null +++ b/frameworks/Python/litestar/ruff.toml @@ -0,0 +1,79 @@ +fix = true +line-length = 120 +src = ["evalai_backend", "tests"] +target-version = "py312" + +[format] +docstring-code-format = true +docstring-code-line-length = 120 +indent-style = "tab" +quote-style = "double" +skip-magic-trailing-comma = false + +[lint] +ignore = [ + "TID252", + "E501", + "S101", + "S102", + "S104", + "S324", + "EXE002", + "D100", + "D102", + "D203", # clash with formatter + "D206", # we use tabs + "D103", + "D104", + "D105", + "D106", + "D101", + "D107", + "D212", + "D211", + "PGH003", + "PGH004", + "N811", + "N804", + "N818", + "N806", + "N815", + "ARG001", + "ARG002", + "DTZ003", + "DTZ005", + "RSE102", + "SLF001", + "PLR", + "INP", + "TRY", + "SIM300", + "SIM114", + "DJ008", + "FIX002", + "S603", + "S607", + "TD002", + "TD003", + "W191", # We use tabs + "COM812", # missing trailing comma + "ISC001", # handled by formatter + "FBT001", + "FBT002", + "FBT003", + "ERA001", +] +select = [ + "ALL" +] + +[lint.flake8-annotations] +suppress-none-returning = true + +[lint.flake8-quotes] +docstring-quotes = "double" +inline-quotes = "double" +multiline-quotes = "double" + +[lint.isort] +combine-as-imports = true From 13583d32df0f1b2be591c8ebbb3ff82fe491ef4d Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 13:23:55 +0530 Subject: [PATCH 05/15] feat: add comprehensive .gitignore for Python and IDE files --- frameworks/Python/litestar/.gitignore | 244 ++++++++++++++++++ .../litestar/__pycache__/app.cpython-312.pyc | Bin 7694 -> 0 bytes .../__pycache__/app_orm.cpython-312.pyc | Bin 8633 -> 0 bytes 3 files changed, 244 insertions(+) create mode 100644 frameworks/Python/litestar/.gitignore delete mode 100644 frameworks/Python/litestar/__pycache__/app.cpython-312.pyc delete mode 100644 frameworks/Python/litestar/__pycache__/app_orm.cpython-312.pyc diff --git a/frameworks/Python/litestar/.gitignore b/frameworks/Python/litestar/.gitignore new file mode 100644 index 00000000000..738a70f9240 --- /dev/null +++ b/frameworks/Python/litestar/.gitignore @@ -0,0 +1,244 @@ +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### PyCharm+all template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +.ruff_cache/ \ No newline at end of file diff --git a/frameworks/Python/litestar/__pycache__/app.cpython-312.pyc b/frameworks/Python/litestar/__pycache__/app.cpython-312.pyc deleted file mode 100644 index 41edeed61781c621f71e9de77474b15f63a11973..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7694 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 Date: Thu, 22 May 2025 13:31:35 +0530 Subject: [PATCH 06/15] feat: update benchmark configuration for Granian support --- .../Python/litestar/benchmark_config.json | 69 +++++-------------- .../litestar/nginx-unit-config-orjson.sh | 26 ------- 2 files changed, 16 insertions(+), 79 deletions(-) delete mode 100755 frameworks/Python/litestar/nginx-unit-config-orjson.sh diff --git a/frameworks/Python/litestar/benchmark_config.json b/frameworks/Python/litestar/benchmark_config.json index 9c0589cb87d..db5e1b9e9a8 100755 --- a/frameworks/Python/litestar/benchmark_config.json +++ b/frameworks/Python/litestar/benchmark_config.json @@ -1,6 +1,7 @@ { "framework": "litestar", - "tests": [{ + "tests": [ + { "default": { "json_url": "/json", "fortune_url": "/fortunes", @@ -62,7 +63,7 @@ "notes": "", "versus": "None" }, - "gunicorn-orjson": { + "gunicorn": { "json_url": "/json", "db_url": "/db", "query_url": "/queries?queries=", @@ -104,7 +105,7 @@ "notes": "", "versus": "None" }, - "hypercorn": { + "granian": { "json_url": "/json", "fortune_url": "/fortunes", "plaintext_url": "/plaintext", @@ -120,15 +121,17 @@ "flavor": "Python3", "orm": "Raw", "platform": "asyncio", - "webserver": "Hypercorn", + "webserver": "Granian", "os": "Linux", "database_os": "Linux", - "display_name": "Litestar-hypercorn", + "display_name": "Litestar-Granian", "notes": "", "versus": "None" }, - "hypercorn-orjson": { + "granian-orm": { "json_url": "/json", + "fortune_url": "/fortunes", + "plaintext_url": "/plaintext", "db_url": "/db", "query_url": "/queries?queries=", "update_url": "/updates?queries=", @@ -141,10 +144,10 @@ "flavor": "Python3", "orm": "Raw", "platform": "asyncio", - "webserver": "Hypercorn", + "webserver": "Granian", "os": "Linux", "database_os": "Linux", - "display_name": "Litestar-hypercorn-orjson", + "display_name": "Litestar-Granian-ORM", "notes": "", "versus": "None" }, @@ -170,29 +173,9 @@ "display_name": "Litestar-nginx-unit", "notes": "", "versus": "None", - "tags": ["broken"] - }, - "nginx-unit-orjson": { - "json_url": "/json", - "db_url": "/db", - "query_url": "/queries?queries=", - "update_url": "/updates?queries=", - "port": 8080, - "approach": "Realistic", - "classification": "Micro", - "database": "Postgres", - "framework": "Litestar", - "language": "Python", - "flavor": "Python3", - "orm": "Raw", - "platform": "asyncio", - "webserver": "nginx-unit", - "os": "Linux", - "database_os": "Linux", - "display_name": "Litestar-nginx-unit-orjson", - "notes": "", - "versus": "None", - "tags": ["broken"] + "tags": [ + "broken" + ] }, "uvicorn": { "json_url": "/json", @@ -216,27 +199,7 @@ "display_name": "Litestar-uvicorn", "notes": "", "versus": "None" - }, - "uvicorn-orjson": { - "json_url": "/json", - "db_url": "/db", - "query_url": "/queries?queries=", - "update_url": "/updates?queries=", - "port": 8080, - "approach": "Realistic", - "classification": "Micro", - "database": "Postgres", - "framework": "Litestar", - "language": "Python", - "flavor": "Python3", - "orm": "Raw", - "platform": "asyncio", - "webserver": "Uvicorn", - "os": "Linux", - "database_os": "Linux", - "display_name": "Litestar-uvicorn-orjson", - "notes": "", - "versus": "None" } - }] + } + ] } diff --git a/frameworks/Python/litestar/nginx-unit-config-orjson.sh b/frameworks/Python/litestar/nginx-unit-config-orjson.sh deleted file mode 100755 index 3f947f13a90..00000000000 --- a/frameworks/Python/litestar/nginx-unit-config-orjson.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -config='{' -config+=' "listeners": {' -config+=' "*:8080": {' -config+=' "pass": "applications/litestar"' -config+=' }' -config+=' },' -config+=' "applications": {' -config+=' "litestar": {' -config+=' "type": "python",' -config+=' "path": "/litestar",' -config+=' "home": "/opt/venv/",' -config+=' "protocol": "asgi",' -config+=' "module": "app",' -config+=' "callable": "app",' -config+=' "processes": '"$(nproc)"',' -config+=' }' -config+=' }', -config+=' "access_log": "/dev/null"' -config+='}' - -curl -X PUT \ - --data-binary "$config" \ - --unix-socket /var/run/control.unit.sock \ - http://localhost/config From f0247bf62834e761928558ecee8ddf07e6c79e07 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 13:39:28 +0530 Subject: [PATCH 07/15] feat: update display names in benchmark configuration and modify Dockerfile installation --- .../Python/litestar/benchmark_config.json | 6 +++--- .../litestar/litestar-granian-orm.dockerfile | 20 +++++++++++++++++++ .../litestar/litestar-gunicorn-orm.dockerfile | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 frameworks/Python/litestar/litestar-granian-orm.dockerfile diff --git a/frameworks/Python/litestar/benchmark_config.json b/frameworks/Python/litestar/benchmark_config.json index db5e1b9e9a8..114e0a8a46c 100755 --- a/frameworks/Python/litestar/benchmark_config.json +++ b/frameworks/Python/litestar/benchmark_config.json @@ -80,7 +80,7 @@ "webserver": "Gunicorn", "os": "Linux", "database_os": "Linux", - "display_name": "Litestar-gunicorn-orjson", + "display_name": "Litestar-gunicorn", "notes": "", "versus": "None" }, @@ -124,7 +124,7 @@ "webserver": "Granian", "os": "Linux", "database_os": "Linux", - "display_name": "Litestar-Granian", + "display_name": "Litestar-granian", "notes": "", "versus": "None" }, @@ -147,7 +147,7 @@ "webserver": "Granian", "os": "Linux", "database_os": "Linux", - "display_name": "Litestar-Granian-ORM", + "display_name": "Litestar-granian-orm", "notes": "", "versus": "None" }, diff --git a/frameworks/Python/litestar/litestar-granian-orm.dockerfile b/frameworks/Python/litestar/litestar-granian-orm.dockerfile new file mode 100644 index 00000000000..413ba821868 --- /dev/null +++ b/frameworks/Python/litestar/litestar-granian-orm.dockerfile @@ -0,0 +1,20 @@ +FROM python:3.13 + +WORKDIR /litestar + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-sqlalchemy.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-sqlalchemy.txt -r requirements-granian.txt + +COPY . ./ + +EXPOSE 8080 + +ENV CONNECTION=ORM + +CMD gunicorn app_orm:app -k uvicorn_worker.UvicornWorker -c litestar_conf.py diff --git a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile index e5b0bedecb0..114e1c3b537 100644 --- a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile +++ b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile @@ -9,7 +9,7 @@ RUN pip3 install cython==3.0.12 COPY requirements.txt requirements-sqlalchemy.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ -RUN pip3 install -r requirements.txt -r requirements-sqlalchemy.txt -r requirements-gunicorn.txt -r requirements-uvicorn.txt +RUN pip3 install -r requirements.txt -r requirements-sqlalchemy.txt -r requirements-gunicorn.txt COPY . ./ From 815860350d783fe87835fd981eaaaf2ba1741407 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 15:22:29 +0530 Subject: [PATCH 08/15] feat: update response handling to return Response objects for JSON endpoints --- .../Python/litestar/app-socketify-asgi.py | 8 ++--- frameworks/Python/litestar/app.py | 36 ++++++++++++------- frameworks/Python/litestar/app_orm.py | 30 +++++++++++----- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/frameworks/Python/litestar/app-socketify-asgi.py b/frameworks/Python/litestar/app-socketify-asgi.py index 9fcdb698d14..2e9de792826 100755 --- a/frameworks/Python/litestar/app-socketify-asgi.py +++ b/frameworks/Python/litestar/app-socketify-asgi.py @@ -3,17 +3,17 @@ import logging import orjson -from litestar import Litestar, get, MediaType +from litestar import Litestar, get, MediaType, Response from socketify import ASGI @get("/json") -async def json_serialization(): - return orjson.dumps({"message": "Hello, world!"}) +async def json_serialization() -> Response: + return Response(content=orjson.dumps({"message": "Hello, world!"}), media_type=MediaType.JSON) @get("/plaintext", media_type=MediaType.TEXT) -async def plaintext(): +async def plaintext() -> bytes: return b"Hello, world!" diff --git a/frameworks/Python/litestar/app.py b/frameworks/Python/litestar/app.py index 67df2ea4f89..cd28ddc4f93 100755 --- a/frameworks/Python/litestar/app.py +++ b/frameworks/Python/litestar/app.py @@ -7,7 +7,7 @@ import asyncpg import orjson -from litestar import Litestar, MediaType, Request, get +from litestar import Litestar, MediaType, Request, get, Response from litestar.contrib.jinja import JinjaTemplateEngine from litestar.response import Template from litestar.template import TemplateConfig @@ -37,10 +37,10 @@ def get_num_queries(queries): async def setup_database(): return await asyncpg.create_pool( - user=os.getenv("PGUSER", "benchmarkdbuser"), - password=os.getenv("PGPASS", "benchmarkdbpass"), - database="hello_world", - host="tfb-database", + user=os.getenv("PGUSER", "postgres"), + password=os.getenv("PGPASS", "password"), + database="postgres", + host="localhost", port=5432, min_size=MIN_POOL_SIZE, max_size=MAX_POOL_SIZE, @@ -57,21 +57,27 @@ async def lifespan(app: Litestar): @get("/json") -async def json_serialization() -> bytes: - return orjson.dumps({"message": "Hello, world!"}) +async def json_serialization() -> Response: + return Response( + content=orjson.dumps({"message": "Hello, world!"}), + media_type=MediaType.JSON, + ) @get("/db") -async def single_database_query() -> bytes: +async def single_database_query() -> Response: row_id = randint(1, 10000) async with app.state.connection_pool.acquire() as connection: number = await connection.fetchval(READ_ROW_SQL, row_id) - return orjson.dumps({"id": row_id, "randomNumber": number}) + return Response( + content=orjson.dumps({"id": row_id, "randomNumber": number}), + media_type=MediaType.JSON, + ) @get("/queries") -async def multiple_database_queries(queries: Any = None) -> bytes: +async def multiple_database_queries(queries: Any = None) -> Response: num_queries = get_num_queries(queries) row_ids = sample(range(1, 10000), num_queries) worlds = [] @@ -82,7 +88,10 @@ async def multiple_database_queries(queries: Any = None) -> bytes: number = await statement.fetchval(row_id) worlds.append({"id": row_id, "randomNumber": number}) - return orjson.dumps(worlds) + return Response( + content=orjson.dumps(worlds), + media_type=MediaType.JSON, + ) @get("/fortunes") @@ -111,7 +120,10 @@ async def database_updates(queries: Any = None) -> bytes: await statement.fetchval(row_id) await connection.executemany(WRITE_ROW_SQL, updates) - return orjson.dumps(worlds) + return Response( + content=orjson.dumps(worlds), + media_type=MediaType.JSON, + ) @get("/plaintext", media_type=MediaType.TEXT) diff --git a/frameworks/Python/litestar/app_orm.py b/frameworks/Python/litestar/app_orm.py index 74d4c9ef1db..cc7fe731c38 100755 --- a/frameworks/Python/litestar/app_orm.py +++ b/frameworks/Python/litestar/app_orm.py @@ -8,7 +8,7 @@ from typing import Any import orjson -from litestar import Litestar, MediaType, Request, get +from litestar import Litestar, MediaType, Request, get, Response from litestar.contrib.jinja import JinjaTemplateEngine from litestar.response import Template from litestar.template import TemplateConfig @@ -90,22 +90,28 @@ def get_num_queries(queries): @get("/json") -async def json_serialization() -> bytes: - return orjson.dumps({"message": "Hello, world!"}) +async def json_serialization() -> Response: + return Response( + content=orjson.dumps({"message": "Hello, world!"}), + media_type=MediaType.JSON, + ) @get("/db") -async def single_database_query() -> bytes: +async def single_database_query() -> Response: id_ = randint(1, 10000) async with app.state.db_session() as sess: result = await sess.get(World, id_) - return orjson.dumps(result.__json__()) + return Response( + content=orjson.dumps(result.__json__()), + media_type=MediaType.JSON, + ) @get("/queries") -async def multiple_database_queries(queries: Any = None) -> bytes: +async def multiple_database_queries(queries: Any = None) -> Response: num_queries = get_num_queries(queries) data = [] @@ -114,7 +120,10 @@ async def multiple_database_queries(queries: Any = None) -> bytes: result = await sess.get(World, id_) data.append(result.__json__()) - return orjson.dumps(data) + return Response( + content=orjson.dumps(data), + media_type=MediaType.JSON, + ) @get("/fortunes") @@ -130,7 +139,7 @@ async def fortunes(request: Request) -> Template: @get("/updates") -async def database_updates(queries: Any = None) -> bytes: +async def database_updates(queries: Any = None) -> Response: num_queries = get_num_queries(queries) ids = sorted(sample(range(1, 10000 + 1), num_queries)) @@ -144,7 +153,10 @@ async def database_updates(queries: Any = None) -> bytes: flag_modified(world, "randomnumber") data.append(world.__json__()) - return orjson.dumps(data) + return Response( + content=orjson.dumps(data), + media_type=MediaType.JSON, + ) @get("/plaintext", media_type=MediaType.TEXT) From 4d51fcde12296f6e0ef2e5ed218afb9f18099b98 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 15:26:16 +0530 Subject: [PATCH 09/15] feat: update response handling to return Response objects for JSON endpoints --- frameworks/Python/litestar/app.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frameworks/Python/litestar/app.py b/frameworks/Python/litestar/app.py index cd28ddc4f93..0a2a0ddd5d0 100755 --- a/frameworks/Python/litestar/app.py +++ b/frameworks/Python/litestar/app.py @@ -37,10 +37,10 @@ def get_num_queries(queries): async def setup_database(): return await asyncpg.create_pool( - user=os.getenv("PGUSER", "postgres"), - password=os.getenv("PGPASS", "password"), - database="postgres", - host="localhost", + user=os.getenv("PGUSER", "benchmarkdbuser"), + password=os.getenv("PGPASS", "benchmarkdbpass"), + database="hello_world", + host="tfb-database", port=5432, min_size=MIN_POOL_SIZE, max_size=MAX_POOL_SIZE, From 6d0ac0ac54d6bfc43e377b064f0838854283842e Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 20:03:38 +0530 Subject: [PATCH 10/15] fix: copy files in Dockerfiles --- frameworks/Python/litestar/litestar-granian-orm.dockerfile | 4 ++-- frameworks/Python/litestar/litestar-granian.dockerfile | 2 +- frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile | 2 +- frameworks/Python/litestar/litestar.dockerfile | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frameworks/Python/litestar/litestar-granian-orm.dockerfile b/frameworks/Python/litestar/litestar-granian-orm.dockerfile index 413ba821868..c6c0640c5b8 100644 --- a/frameworks/Python/litestar/litestar-granian-orm.dockerfile +++ b/frameworks/Python/litestar/litestar-granian-orm.dockerfile @@ -7,7 +7,7 @@ ENV PATH="/opt/venv/bin:$PATH" RUN pip3 install cython==3.0.12 -COPY requirements.txt requirements-sqlalchemy.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ +COPY requirements.txt requirements-sqlalchemy.txt requirements-granian.txt ./ RUN pip3 install -r requirements.txt -r requirements-sqlalchemy.txt -r requirements-granian.txt @@ -17,4 +17,4 @@ EXPOSE 8080 ENV CONNECTION=ORM -CMD gunicorn app_orm:app -k uvicorn_worker.UvicornWorker -c litestar_conf.py +CMD granian --interface asgi app:app --host '0.0.0.0' --port 8080 --workers $(nproc) --http 2 diff --git a/frameworks/Python/litestar/litestar-granian.dockerfile b/frameworks/Python/litestar/litestar-granian.dockerfile index f44571fb483..aab7a63c08d 100644 --- a/frameworks/Python/litestar/litestar-granian.dockerfile +++ b/frameworks/Python/litestar/litestar-granian.dockerfile @@ -7,7 +7,7 @@ ENV PATH="/opt/venv/bin:$PATH" RUN pip3 install cython==3.0.12 -COPY requirements.txt requirements-hypercorn.txt ./ +COPY requirements.txt requirements-granian.txt ./ RUN pip3 install -r requirements.txt -r requirements-granian.txt diff --git a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile index 114e1c3b537..a5c01176b32 100644 --- a/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile +++ b/frameworks/Python/litestar/litestar-gunicorn-orm.dockerfile @@ -7,7 +7,7 @@ ENV PATH="/opt/venv/bin:$PATH" RUN pip3 install cython==3.0.12 -COPY requirements.txt requirements-sqlalchemy.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ +COPY requirements.txt requirements-sqlalchemy.txt requirements-gunicorn.txt ./ RUN pip3 install -r requirements.txt -r requirements-sqlalchemy.txt -r requirements-gunicorn.txt diff --git a/frameworks/Python/litestar/litestar.dockerfile b/frameworks/Python/litestar/litestar.dockerfile index 1df7f8b4d7e..6d3d793e6fc 100644 --- a/frameworks/Python/litestar/litestar.dockerfile +++ b/frameworks/Python/litestar/litestar.dockerfile @@ -7,9 +7,9 @@ ENV PATH="/opt/venv/bin:$PATH" RUN pip3 install cython==3.0.12 -COPY requirements.txt requirements-gunicorn.txt requirements-uvicorn.txt ./ +COPY requirements.txt requirements-gunicorn.txt ./ -RUN pip3 install -r requirements.txt -r requirements-gunicorn.txt -r requirements-uvicorn.txt +RUN pip3 install -r requirements.txt -r requirements-gunicorn.txt COPY . ./ From 6a115ad8e228a1c5c96b3b664a3397f8a1912e9d Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 20:04:40 +0530 Subject: [PATCH 11/15] fix: copy files in Dockerfiles --- frameworks/Python/litestar/app.py | 8 ++++++-- frameworks/Python/litestar/app_orm.py | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/frameworks/Python/litestar/app.py b/frameworks/Python/litestar/app.py index 0a2a0ddd5d0..2075f4fc8d7 100755 --- a/frameworks/Python/litestar/app.py +++ b/frameworks/Python/litestar/app.py @@ -94,14 +94,18 @@ async def multiple_database_queries(queries: Any = None) -> Response: ) -@get("/fortunes") +@get("/fortunes", media_type=MediaType.TEXT) async def fortunes(request: Request) -> Template: async with app.state.connection_pool.acquire() as connection: fortunes = await connection.fetch("SELECT * FROM Fortune") fortunes.append(ADDITIONAL_ROW) fortunes.sort(key=lambda row: row[1]) - return Template("fortune.html", context={"fortunes": fortunes, "request": request}) + return Template( + "fortune.html", + context={"fortunes": fortunes, "request": request}, + media_type=MediaType.TEXT, + ) @get("/updates") diff --git a/frameworks/Python/litestar/app_orm.py b/frameworks/Python/litestar/app_orm.py index cc7fe731c38..f132c9aa442 100755 --- a/frameworks/Python/litestar/app_orm.py +++ b/frameworks/Python/litestar/app_orm.py @@ -126,7 +126,7 @@ async def multiple_database_queries(queries: Any = None) -> Response: ) -@get("/fortunes") +@get("/fortunes", media_type=MediaType.TEXT) async def fortunes(request: Request) -> Template: async with app.state.db_session() as sess: ret = await sess.execute(select(Fortune.id, Fortune.message)) @@ -135,7 +135,11 @@ async def fortunes(request: Request) -> Template: data.append(ADDITIONAL_FORTUNE) data.sort(key=sort_fortunes_key) - return Template("fortune.jinja", context={"request": request, "fortunes": data}) + return Template( + "fortune.jinja", + context={"request": request, "fortunes": data}, + media_type=MediaType.TEXT, + ) @get("/updates") From 01aa2603f9c6a3dd7aea464217074fc8c6583c97 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 20:05:52 +0530 Subject: [PATCH 12/15] fix: remove usage of restricting to http2 --- frameworks/Python/litestar/litestar-granian-orm.dockerfile | 2 +- frameworks/Python/litestar/litestar-granian.dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Python/litestar/litestar-granian-orm.dockerfile b/frameworks/Python/litestar/litestar-granian-orm.dockerfile index c6c0640c5b8..72c989b5f42 100644 --- a/frameworks/Python/litestar/litestar-granian-orm.dockerfile +++ b/frameworks/Python/litestar/litestar-granian-orm.dockerfile @@ -17,4 +17,4 @@ EXPOSE 8080 ENV CONNECTION=ORM -CMD granian --interface asgi app:app --host '0.0.0.0' --port 8080 --workers $(nproc) --http 2 +CMD granian --interface asgi app:app --host '0.0.0.0' --port 8080 --workers $(nproc) diff --git a/frameworks/Python/litestar/litestar-granian.dockerfile b/frameworks/Python/litestar/litestar-granian.dockerfile index aab7a63c08d..ae838eaedf6 100644 --- a/frameworks/Python/litestar/litestar-granian.dockerfile +++ b/frameworks/Python/litestar/litestar-granian.dockerfile @@ -15,4 +15,4 @@ COPY . ./ EXPOSE 8080 -CMD granian --interface asgi app:app --host '0.0.0.0' --port 8080 --workers $(nproc) --http 2 +CMD granian --interface asgi app:app --host '0.0.0.0' --port 8080 --workers $(nproc) From 4fac0297ed1e593f1c2460f4158110b22e41c3d7 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 20:25:34 +0530 Subject: [PATCH 13/15] fix: resposne types --- frameworks/Python/litestar/app.py | 4 ++-- frameworks/Python/litestar/app_orm.py | 4 ++-- .../{litestar.dockerfile => litestar-gunicorn.dockerfile} | 0 3 files changed, 4 insertions(+), 4 deletions(-) rename frameworks/Python/litestar/{litestar.dockerfile => litestar-gunicorn.dockerfile} (100%) diff --git a/frameworks/Python/litestar/app.py b/frameworks/Python/litestar/app.py index 2075f4fc8d7..6c5d0678ad9 100755 --- a/frameworks/Python/litestar/app.py +++ b/frameworks/Python/litestar/app.py @@ -94,7 +94,7 @@ async def multiple_database_queries(queries: Any = None) -> Response: ) -@get("/fortunes", media_type=MediaType.TEXT) +@get("/fortunes", media_type=MediaType.HTML) async def fortunes(request: Request) -> Template: async with app.state.connection_pool.acquire() as connection: fortunes = await connection.fetch("SELECT * FROM Fortune") @@ -104,7 +104,7 @@ async def fortunes(request: Request) -> Template: return Template( "fortune.html", context={"fortunes": fortunes, "request": request}, - media_type=MediaType.TEXT, + media_type=MediaType.HTML, ) diff --git a/frameworks/Python/litestar/app_orm.py b/frameworks/Python/litestar/app_orm.py index f132c9aa442..ab7f415450c 100755 --- a/frameworks/Python/litestar/app_orm.py +++ b/frameworks/Python/litestar/app_orm.py @@ -126,7 +126,7 @@ async def multiple_database_queries(queries: Any = None) -> Response: ) -@get("/fortunes", media_type=MediaType.TEXT) +@get("/fortunes", media_type=MediaType.HTML) async def fortunes(request: Request) -> Template: async with app.state.db_session() as sess: ret = await sess.execute(select(Fortune.id, Fortune.message)) @@ -138,7 +138,7 @@ async def fortunes(request: Request) -> Template: return Template( "fortune.jinja", context={"request": request, "fortunes": data}, - media_type=MediaType.TEXT, + media_type=MediaType.HTML, ) diff --git a/frameworks/Python/litestar/litestar.dockerfile b/frameworks/Python/litestar/litestar-gunicorn.dockerfile similarity index 100% rename from frameworks/Python/litestar/litestar.dockerfile rename to frameworks/Python/litestar/litestar-gunicorn.dockerfile From 7fdf1f526aac63d63b7faab29f97f20c8e3c3165 Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Thu, 22 May 2025 20:29:57 +0530 Subject: [PATCH 14/15] fix: resposne types --- frameworks/Python/litestar/litestar.dockerfile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 frameworks/Python/litestar/litestar.dockerfile diff --git a/frameworks/Python/litestar/litestar.dockerfile b/frameworks/Python/litestar/litestar.dockerfile new file mode 100644 index 00000000000..6d3d793e6fc --- /dev/null +++ b/frameworks/Python/litestar/litestar.dockerfile @@ -0,0 +1,18 @@ +FROM python:3.13 + +WORKDIR /litestar + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +RUN pip3 install cython==3.0.12 + +COPY requirements.txt requirements-gunicorn.txt ./ + +RUN pip3 install -r requirements.txt -r requirements-gunicorn.txt + +COPY . ./ + +EXPOSE 8080 + +CMD gunicorn app:app -k uvicorn_worker.UvicornWorker -c litestar_conf.py From 657d83b42c860f5f927ccf63c2c4fd402e4a3b2b Mon Sep 17 00:00:00 2001 From: Vetrichelvan Date: Wed, 6 Aug 2025 18:38:11 +0530 Subject: [PATCH 15/15] fix: remove socketify with pypy --- .../Python/litestar/benchmark_config.json | 19 ------------------- .../litestar-socketify-asgi-pypy.dockerfile | 16 ---------------- .../litestar/requirements-socketify-pypy.txt | 2 -- 3 files changed, 37 deletions(-) delete mode 100644 frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile delete mode 100644 frameworks/Python/litestar/requirements-socketify-pypy.txt diff --git a/frameworks/Python/litestar/benchmark_config.json b/frameworks/Python/litestar/benchmark_config.json index 114e0a8a46c..1f94fc49174 100755 --- a/frameworks/Python/litestar/benchmark_config.json +++ b/frameworks/Python/litestar/benchmark_config.json @@ -44,25 +44,6 @@ "notes": "", "versus": "None" }, - "socketify-asgi-pypy": { - "json_url": "/json", - "plaintext_url": "/plaintext", - "port": 8080, - "approach": "Realistic", - "classification": "Micro", - "database": "Postgres", - "framework": "Litestar", - "language": "Python", - "flavor": "Python3", - "orm": "Raw", - "platform": "asyncio", - "webserver": "Socketify.py", - "os": "Linux", - "database_os": "Linux", - "display_name": "Litestar [Socketify.py ASGI PyPy3]", - "notes": "", - "versus": "None" - }, "gunicorn": { "json_url": "/json", "db_url": "/db", diff --git a/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile b/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile deleted file mode 100644 index 6a778fdc075..00000000000 --- a/frameworks/Python/litestar/litestar-socketify-asgi-pypy.dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM pypy:3.11-bookworm - -WORKDIR /litestar - -RUN python -m venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" - -COPY requirements-socketify-pypy.txt ./ -RUN apt-get update; apt-get install libuv1 -y -RUN pip3 install -r requirements-socketify-pypy.txt - -COPY . ./ - -EXPOSE 8080 - -CMD python ./app-socketify-asgi.py diff --git a/frameworks/Python/litestar/requirements-socketify-pypy.txt b/frameworks/Python/litestar/requirements-socketify-pypy.txt deleted file mode 100644 index 393fdeebfca..00000000000 --- a/frameworks/Python/litestar/requirements-socketify-pypy.txt +++ /dev/null @@ -1,2 +0,0 @@ -litestar==2.16.0 -git+https://github.com/cirospaciari/socketify.py.git@main#socketify