diff --git a/test-django-uwsgi-fileresponse/.python-version b/test-django-uwsgi-fileresponse/.python-version new file mode 100644 index 0000000..6324d40 --- /dev/null +++ b/test-django-uwsgi-fileresponse/.python-version @@ -0,0 +1 @@ +3.14 diff --git a/test-django-uwsgi-fileresponse/README.md b/test-django-uwsgi-fileresponse/README.md new file mode 100644 index 0000000..7190a0f --- /dev/null +++ b/test-django-uwsgi-fileresponse/README.md @@ -0,0 +1,4 @@ +# Run command for uWSGI server +`uwsgi --ini uwsgi.ini` + +Visit `http://localhost:8000/get-image/` to test. \ No newline at end of file diff --git a/test-django-uwsgi-fileresponse/main.py b/test-django-uwsgi-fileresponse/main.py new file mode 100644 index 0000000..4a030da --- /dev/null +++ b/test-django-uwsgi-fileresponse/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from test-django-uwsgi-fileresponse!") + + +if __name__ == "__main__": + main() diff --git a/test-django-uwsgi-fileresponse/manage.py b/test-django-uwsgi-fileresponse/manage.py new file mode 100755 index 0000000..a7da667 --- /dev/null +++ b/test-django-uwsgi-fileresponse/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/test-django-uwsgi-fileresponse/mysite/__init__.py b/test-django-uwsgi-fileresponse/mysite/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test-django-uwsgi-fileresponse/mysite/asgi.py b/test-django-uwsgi-fileresponse/mysite/asgi.py new file mode 100644 index 0000000..540f6e4 --- /dev/null +++ b/test-django-uwsgi-fileresponse/mysite/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for mysite project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') + +application = get_asgi_application() diff --git a/test-django-uwsgi-fileresponse/mysite/sample_image.png b/test-django-uwsgi-fileresponse/mysite/sample_image.png new file mode 100644 index 0000000..8bcbd28 Binary files /dev/null and b/test-django-uwsgi-fileresponse/mysite/sample_image.png differ diff --git a/test-django-uwsgi-fileresponse/mysite/settings.py b/test-django-uwsgi-fileresponse/mysite/settings.py new file mode 100644 index 0000000..4383fed --- /dev/null +++ b/test-django-uwsgi-fileresponse/mysite/settings.py @@ -0,0 +1,126 @@ +""" +Django settings for mysite project. + +Generated by 'django-admin startproject' using Django 6.0.2. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/6.0/ref/settings/ +""" + +import os +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-fshyd7=m%t_wswrc*)t2(in)^oeim%jh#4!bc&k$bksg8_skdl' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'mysite.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'mysite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/6.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/6.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/6.0/howto/static-files/ + +STATIC_URL = 'static/' + +import sentry_sdk + +sentry_sdk.init( + dsn=os.environ.get("SENTRY_DSN"), + enable_tracing=True, + debug=True, +) \ No newline at end of file diff --git a/test-django-uwsgi-fileresponse/mysite/urls.py b/test-django-uwsgi-fileresponse/mysite/urls.py new file mode 100644 index 0000000..8092426 --- /dev/null +++ b/test-django-uwsgi-fileresponse/mysite/urls.py @@ -0,0 +1,24 @@ +""" +URL configuration for mysite project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/6.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path +from . import views + +urlpatterns = [ + path('admin/', admin.site.urls), + path('get-image/', views.get_image, name='get_image'), +] diff --git a/test-django-uwsgi-fileresponse/mysite/views.py b/test-django-uwsgi-fileresponse/mysite/views.py new file mode 100644 index 0000000..85b91cb --- /dev/null +++ b/test-django-uwsgi-fileresponse/mysite/views.py @@ -0,0 +1,6 @@ +from django.http import FileResponse, HttpResponse +import os + +def get_image(request): + image_path = os.path.join(os.path.dirname(__file__), 'sample_image.png') + return FileResponse(open(image_path, 'rb'), content_type='image/png') diff --git a/test-django-uwsgi-fileresponse/mysite/wsgi.py b/test-django-uwsgi-fileresponse/mysite/wsgi.py new file mode 100644 index 0000000..ba5b07b --- /dev/null +++ b/test-django-uwsgi-fileresponse/mysite/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for mysite project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') + +application = get_wsgi_application() diff --git a/test-django-uwsgi-fileresponse/pyproject.toml b/test-django-uwsgi-fileresponse/pyproject.toml new file mode 100644 index 0000000..62a3c92 --- /dev/null +++ b/test-django-uwsgi-fileresponse/pyproject.toml @@ -0,0 +1,19 @@ +[project] +name = "test-django-uwsgi-fileresponse" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.14" +dependencies = [ + "django>=6.0.2", + "sentry-sdk>=2.53.0", + "uwsgi>=2.0.31", +] + +[tool.uv.sources] +sentry-sdk = { path = "../../sentry-python", editable = true } + +[dependency-groups] +dev = [ + "remote-pdb>=2.1.0", +] diff --git a/test-django-uwsgi-fileresponse/uv.lock b/test-django-uwsgi-fileresponse/uv.lock new file mode 100644 index 0000000..6e4d110 --- /dev/null +++ b/test-django-uwsgi-fileresponse/uv.lock @@ -0,0 +1,170 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "asgiref" +version = "3.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/40/f03da1264ae8f7cfdbf9146542e5e7e8100a4c66ab48e791df9a03d3f6c0/asgiref-3.11.1.tar.gz", hash = "sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce", size = 38550, upload-time = "2026-02-03T13:30:14.33Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/0a/a72d10ed65068e115044937873362e6e32fab1b7dce0046aeb224682c989/asgiref-3.11.1-py3-none-any.whl", hash = "sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133", size = 24345, upload-time = "2026-02-03T13:30:13.039Z" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "django" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asgiref" }, + { name = "sqlparse" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/3e/a1c4207c5dea4697b7a3387e26584919ba987d8f9320f59dc0b5c557a4eb/django-6.0.2.tar.gz", hash = "sha256:3046a53b0e40d4b676c3b774c73411d7184ae2745fe8ce5e45c0f33d3ddb71a7", size = 10886874, upload-time = "2026-02-03T13:50:31.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/ba/a6e2992bc5b8c688249c00ea48cb1b7a9bc09839328c81dc603671460928/django-6.0.2-py3-none-any.whl", hash = "sha256:610dd3b13d15ec3f1e1d257caedd751db8033c5ad8ea0e2d1219a8acf446ecc6", size = 8339381, upload-time = "2026-02-03T13:50:15.501Z" }, +] + +[[package]] +name = "remote-pdb" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/b5/4944cac06fd9fc4a2e168313ec220aa25ed96ce83947b63eea5b4045b22d/remote-pdb-2.1.0.tar.gz", hash = "sha256:2d70c6f41e0eabf0165e8f1be58f82aa7a605aaeab8f2aefeb9ce246431091c1", size = 22295, upload-time = "2020-07-24T13:31:32.985Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/c5/d208c66344bb785d800adb61aef512290d3473052b9e7697890f0547aff2/remote_pdb-2.1.0-py2.py3-none-any.whl", hash = "sha256:94f73a92ac1248cf16189211011f97096bdada8a7baac8c79372663bbb57b5d0", size = 6304, upload-time = "2020-07-24T13:31:31.535Z" }, +] + +[[package]] +name = "sentry-sdk" +version = "2.53.0" +source = { editable = "../../sentry-python" } +dependencies = [ + { name = "certifi" }, + { name = "urllib3" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", marker = "extra == 'aiohttp'", specifier = ">=3.5" }, + { name = "anthropic", marker = "extra == 'anthropic'", specifier = ">=0.16" }, + { name = "apache-beam", marker = "extra == 'beam'", specifier = ">=2.12" }, + { name = "arq", marker = "extra == 'arq'", specifier = ">=0.23" }, + { name = "asttokens", marker = "extra == 'pure-eval'" }, + { name = "asyncpg", marker = "extra == 'asyncpg'", specifier = ">=0.23" }, + { name = "blinker", marker = "extra == 'flask'", specifier = ">=1.1" }, + { name = "blinker", marker = "extra == 'quart'", specifier = ">=1.1" }, + { name = "bottle", marker = "extra == 'bottle'", specifier = ">=0.12.13" }, + { name = "celery", marker = "extra == 'celery'", specifier = ">=3" }, + { name = "celery-redbeat", marker = "extra == 'celery-redbeat'", specifier = ">=2" }, + { name = "certifi" }, + { name = "chalice", marker = "extra == 'chalice'", specifier = ">=1.16.0" }, + { name = "clickhouse-driver", marker = "extra == 'clickhouse-driver'", specifier = ">=0.2.0" }, + { name = "django", marker = "extra == 'django'", specifier = ">=1.8" }, + { name = "executing", marker = "extra == 'pure-eval'" }, + { name = "falcon", marker = "extra == 'falcon'", specifier = ">=1.4" }, + { name = "fastapi", marker = "extra == 'fastapi'", specifier = ">=0.79.0" }, + { name = "flask", marker = "extra == 'flask'", specifier = ">=0.11" }, + { name = "google-genai", marker = "extra == 'google-genai'", specifier = ">=1.29.0" }, + { name = "grpcio", marker = "extra == 'grpcio'", specifier = ">=1.21.1" }, + { name = "httpcore", extras = ["http2"], marker = "extra == 'http2'", specifier = "==1.*" }, + { name = "httpx", marker = "extra == 'httpx'", specifier = ">=0.16.0" }, + { name = "huey", marker = "extra == 'huey'", specifier = ">=2" }, + { name = "huggingface-hub", marker = "extra == 'huggingface-hub'", specifier = ">=0.22" }, + { name = "langchain", marker = "extra == 'langchain'", specifier = ">=0.0.210" }, + { name = "langgraph", marker = "extra == 'langgraph'", specifier = ">=0.6.6" }, + { name = "launchdarkly-server-sdk", marker = "extra == 'launchdarkly'", specifier = ">=9.8.0" }, + { name = "litellm", marker = "extra == 'litellm'", specifier = ">=1.77.5" }, + { name = "litestar", marker = "extra == 'litestar'", specifier = ">=2.0.0" }, + { name = "loguru", marker = "extra == 'loguru'", specifier = ">=0.5" }, + { name = "markupsafe", marker = "extra == 'flask'" }, + { name = "mcp", marker = "extra == 'mcp'", specifier = ">=1.15.0" }, + { name = "openai", marker = "extra == 'openai'", specifier = ">=1.0.0" }, + { name = "openfeature-sdk", marker = "extra == 'openfeature'", specifier = ">=0.7.1" }, + { name = "opentelemetry-distro", marker = "extra == 'opentelemetry'", specifier = ">=0.35b0" }, + { name = "opentelemetry-distro", marker = "extra == 'opentelemetry-experimental'" }, + { name = "opentelemetry-distro", extras = ["otlp"], marker = "extra == 'opentelemetry-otlp'", specifier = ">=0.35b0" }, + { name = "protobuf", marker = "extra == 'grpcio'", specifier = ">=3.8.0" }, + { name = "pure-eval", marker = "extra == 'pure-eval'" }, + { name = "pydantic-ai", marker = "extra == 'pydantic-ai'", specifier = ">=1.0.0" }, + { name = "pymongo", marker = "extra == 'pymongo'", specifier = ">=3.1" }, + { name = "pyspark", marker = "extra == 'pyspark'", specifier = ">=2.4.4" }, + { name = "quart", marker = "extra == 'quart'", specifier = ">=0.16.1" }, + { name = "rq", marker = "extra == 'rq'", specifier = ">=0.6" }, + { name = "sanic", marker = "extra == 'sanic'", specifier = ">=0.8" }, + { name = "sqlalchemy", marker = "extra == 'sqlalchemy'", specifier = ">=1.2" }, + { name = "starlette", marker = "extra == 'starlette'", specifier = ">=0.19.1" }, + { name = "starlite", marker = "extra == 'starlite'", specifier = ">=1.48" }, + { name = "statsig", marker = "extra == 'statsig'", specifier = ">=0.55.3" }, + { name = "tiktoken", marker = "extra == 'openai'", specifier = ">=0.3.0" }, + { name = "tornado", marker = "extra == 'tornado'", specifier = ">=6" }, + { name = "unleashclient", marker = "extra == 'unleash'", specifier = ">=6.0.1" }, + { name = "urllib3", specifier = ">=1.26.11" }, +] +provides-extras = ["aiohttp", "anthropic", "arq", "asyncpg", "beam", "bottle", "celery", "celery-redbeat", "chalice", "clickhouse-driver", "django", "falcon", "fastapi", "flask", "grpcio", "http2", "httpx", "huey", "huggingface-hub", "langchain", "langgraph", "launchdarkly", "litellm", "litestar", "loguru", "mcp", "openai", "openfeature", "opentelemetry", "opentelemetry-experimental", "opentelemetry-otlp", "pure-eval", "pydantic-ai", "pymongo", "pyspark", "quart", "rq", "sanic", "sqlalchemy", "starlette", "starlite", "statsig", "tornado", "unleash", "google-genai"] + +[[package]] +name = "sqlparse" +version = "0.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/76/437d71068094df0726366574cf3432a4ed754217b436eb7429415cf2d480/sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e", size = 120815, upload-time = "2025-12-19T07:17:45.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/4b/359f28a903c13438ef59ebeee215fb25da53066db67b305c125f1c6d2a25/sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba", size = 46138, upload-time = "2025-12-19T07:17:46.573Z" }, +] + +[[package]] +name = "test-django-uwsgi-fileresponse" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "django" }, + { name = "sentry-sdk" }, + { name = "uwsgi" }, +] + +[package.dev-dependencies] +dev = [ + { name = "remote-pdb" }, +] + +[package.metadata] +requires-dist = [ + { name = "django", specifier = ">=6.0.2" }, + { name = "sentry-sdk", editable = "../../sentry-python" }, + { name = "uwsgi", specifier = ">=2.0.31" }, +] + +[package.metadata.requires-dev] +dev = [{ name = "remote-pdb", specifier = ">=2.1.0" }] + +[[package]] +name = "tzdata" +version = "2025.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "uwsgi" +version = "2.0.31" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/49/2f57640e889ba509fd1fae10cccec1b58972a07c2724486efba94c5ea448/uwsgi-2.0.31.tar.gz", hash = "sha256:e8f8b350ccc106ff93a65247b9136f529c14bf96b936ac5b264c6ff9d0c76257", size = 822796, upload-time = "2025-10-11T19:17:28.794Z" } diff --git a/test-django-uwsgi-fileresponse/uwsgi.ini b/test-django-uwsgi-fileresponse/uwsgi.ini new file mode 100644 index 0000000..d829a42 --- /dev/null +++ b/test-django-uwsgi-fileresponse/uwsgi.ini @@ -0,0 +1,12 @@ +[uwsgi] +module = mysite.wsgi:application + +http = :8000 +master = true +processes = 1 +threads = 1 + +chdir = . +virtualenv = .venv + +env = DJANGO_SETTINGS_MODULE=mysite.settings