{"id":45474692,"url":"https://github.com/l1ghtn1ng/flasgo","last_synced_at":"2026-05-04T05:04:06.650Z","repository":{"id":339889259,"uuid":"1161958301","full_name":"L1ghtn1ng/flasgo","owner":"L1ghtn1ng","description":"A python web framework thats modern and fast with the simplistacty of flask with certain addtional features that you can get in django as its a hybrid of the two","archived":false,"fork":false,"pushed_at":"2026-02-26T14:43:39.000Z","size":102,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-26T22:29:48.631Z","etag":null,"topics":["framework","frontend-web","library","python","python-library","python3","web-development","webdevelopment"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/L1ghtn1ng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"L1ghtn1ng"}},"created_at":"2026-02-19T18:00:21.000Z","updated_at":"2026-02-26T14:43:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/L1ghtn1ng/flasgo","commit_stats":null,"previous_names":["l1ghtn1ng/fango"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/L1ghtn1ng/flasgo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/L1ghtn1ng%2Fflasgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/L1ghtn1ng%2Fflasgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/L1ghtn1ng%2Fflasgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/L1ghtn1ng%2Fflasgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/L1ghtn1ng","download_url":"https://codeload.github.com/L1ghtn1ng/flasgo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/L1ghtn1ng%2Fflasgo/sbom","scorecard":{"id":1243796,"data":{"date":"2026-02-22T14:07:25Z","repo":{"name":"github.com/L1ghtn1ng/flasgo","commit":"4209c30a54c709e71e8a881a79cc9979b6096f3a"},"scorecard":{"version":"v5.0.0","commit":"ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4"},"score":6.1,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disable on branch 'main'","Warn: could not determine whether codeowners review is allowed","Warn: no status checks found to merge onto branch 'main'","Warn: PRs are not required to make changes on branch 'main'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":8,"reason":"7 out of 8 merged PRs checked by a CI test -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#ci-tests"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":1,"reason":"Found 1/10 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#code-review"}},{"name":"Contributors","score":0,"reason":"project has 0 contributing companies or organizations -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#contributors"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dependency-update-tool"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#license"}},{"name":"Maintained","score":0,"reason":"project was created in last 90 days. please review its contents carefully","details":["Warn: Repository was created in last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  13 out of  13 GitHub-owned GitHubAction dependencies pinned","Info:   8 out of   8 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":8,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 10 commits out of 16 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#sast"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#signed-releases"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:31","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:32","Info: jobLevel 'contents' permission set to 'read': .github/workflows/release-pypi.yml:16","Info: jobLevel 'issues' permission set to 'read': .github/workflows/scorecards.yml:32","Info: jobLevel 'pull-requests' permission set to 'read': .github/workflows/scorecards.yml:33","Info: jobLevel 'checks' permission set to 'read': .github/workflows/scorecards.yml:35","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecards.yml:29","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecards.yml:30","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:24","Info: topLevel 'contents' permission set to 'read': .github/workflows/dependency-review.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/release-pypi.yml:9","Info: topLevel permissions set to 'read-all': .github/workflows/scorecards.yml:18","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2026-02-22T15:16:38.497Z","repository_id":339889259,"created_at":"2026-02-22T15:16:38.497Z","updated_at":"2026-02-22T15:16:38.497Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29951672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T18:42:55.706Z","status":"ssl_error","status_checked_at":"2026-02-28T18:42:48.811Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","frontend-web","library","python","python-library","python3","web-development","webdevelopment"],"created_at":"2026-02-22T14:46:17.242Z","updated_at":"2026-05-04T05:04:06.643Z","avatar_url":"https://github.com/L1ghtn1ng.png","language":"Python","funding_links":["https://github.com/sponsors/L1ghtn1ng"],"categories":[],"sub_categories":[],"readme":"# Flasgo\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/L1ghtn1ng/flasgo) [![PyPI version](https://badge.fury.io/py/flasgo.svg)](https://badge.fury.io/py/flasgo)\n\nFlasgo is an async-first Python web framework designed as a hybrid of:\n- Flask ergonomics: decorator-based routing, minimal ceremony, quick iteration.\n- Django security defaults: CSRF protection, host validation, secure headers, signed sessions.\n\n## Project goals\n\n- Fast request handling with an ASGI core.\n- First-class async support.\n- Type-safe APIs with strict tooling.\n- Minimal moving parts and sensible defaults.\n\n## Requirements\n\n- Python `\u003e=3.14`\n- Tooling: `uv`, `ruff`, `ty`, `pytest`\n\n## Install in your project\n\n```bash\nuv add flasgo\n```\n\nOr with `pip`:\n\n```bash\npip install flasgo\n```\n\n## Quick start\n\n```bash\nuv venv\nuv sync --group dev\n```\n\nCreate `app.py`:\n\n```python\nimport os\nimport secrets\n\nfrom flasgo import Flasgo, Request, Response, redirect\n\napp = Flasgo(\n    static_folder=\"static\",\n    settings={\n        \"DEBUG\": True,\n        \"SECRET_KEY\": os.environ.get(\"FLASGO_SECRET_KEY\", secrets.token_urlsafe(32)),\n        \"ALLOWED_HOSTS\": {\"127.0.0.1\", \"localhost\"},\n        \"CSRF_ENABLED\": True,\n        \"SESSION_COOKIE_SECURE\": False,\n        \"CSRF_COOKIE_SECURE\": False,\n    },\n)\n\n\n@app.get(\"/\")\nasync def home():\n    return {\"framework\": \"flasgo\", \"status\": \"ok\"}\n\n\n@app.post(\"/contact\")\nasync def contact(request: Request) -\u003e Response:\n    form = await request.form()\n    if form.get(\"email\"):\n        return redirect(\"/thanks\")\n    return Response.json({\"error\": \"email is required\"}, status_code=400)\n\n\nif __name__ == \"__main__\":\n    app.run(host=\"127.0.0.1\", port=8000, reload=True)\n```\n\nRun:\n\n```bash\nexport FLASGO_SECRET_KEY=\"$(openssl rand -hex 32)\"\nuv run flasgo run app.py --reload\n```\n\n## Development run\n\nBuilt-in dev server with automatic reload:\n\n```bash\nuv run flasgo run app.py --reload\n```\n\nOr explicitly:\n\n```python\napp.run(host=\"127.0.0.1\", port=8000, reload=True)\n```\n\nThe CLI also accepts import strings:\n\n```bash\nuv run flasgo run package.module:app --reload\n```\n\nYou can still use `uvicorn` with reload:\n\n```bash\nuv run uvicorn app:app --reload --host 127.0.0.1 --port 8000\n```\n\n`app.run(...)` uses the built-in dev server and should only be used for local development.\n\n## Production deployment\n\nUse a production ASGI server process and configure secrets with environment variables:\n\n```python\nimport os\nfrom flasgo import Flasgo\n\napp = Flasgo(\n    settings={\n        \"DEBUG\": False,\n        \"SECRET_KEY\": os.environ[\"FLASGO_SECRET_KEY\"],\n        \"ALLOWED_HOSTS\": {\"api.example.com\"},\n        \"CSRF_ENABLED\": True,\n        \"SESSION_COOKIE_SECURE\": True,\n        \"CSRF_COOKIE_SECURE\": True,\n        \"SESSION_COOKIE_HTTP_ONLY\": True,\n    }\n)\n```\n\nRun with workers:\n\n```bash\nexport FLASGO_SECRET_KEY=\"$(openssl rand -hex 32)\"\nuv run uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4\n```\n\nPut a reverse proxy/load balancer in front (Caddy, Cloudflare, etc.) for TLS termination and network controls.\n\n## Security defaults\n\n- Host header allowlist (`localhost`, `127.0.0.1` by default).\n- CSRF double-submit cookie defense for unsafe methods.\n- Signed session cookies (HMAC-SHA256).\n- No-store cache headers by default to reduce sensitive data caching (CWE-524 mitigation).\n- Static file path traversal and symlink escape protections.\n- Request body/head limits and read timeouts in the built-in dev server.\n- Optional per-client throttling for repeated security failures (`429`).\n- Security event logging for host/CSRF/authz denials.\n- Hardened headers (`CSP`, `HSTS`, `X-Frame-Options`, `Referrer-Policy`, etc.).\n\nThese defaults are intended to help teams avoid common OWASP Top 10 2025 failure modes around broken access control, cryptographic failures, security misconfiguration, software and data integrity issues, and SSRF.\n\n## Developer commands\n\n```bash\nuv run ruff check .\nuv run ty check\nuv run pytest\n```\n\n## API surface (initial)\n\n- CLI: `flasgo run app.py --reload`, `flasgo run package.module:app --reload`\n- `Flasgo.route`, `Flasgo.get`, `Flasgo.post`, `Flasgo.put`, `Flasgo.patch`, `Flasgo.delete`\n- `Flasgo.before_request`, `Flasgo.after_request`, `Flasgo.errorhandler`\n- `Flasgo.register_auth_backend`, `Flasgo.authorize`\n- `Flasgo.configure_templates`, `Flasgo.render_template`\n- `Flasgo.configure_static`, `Flasgo.test_client`\n- `Flasgo.openapi_spec`\n- Auth helpers: `bearer_token_backend`, `extract_bearer_token`\n- Templating helpers: `JinjaTemplates`, `render_template`, `Response.template`\n- Request helpers: `await request.form()`, `UploadedFile`\n- Response helpers: `redirect`, `Response.redirect`\n- Flask-style path params: `\u003cname\u003e`, `\u003cint:name\u003e`, `\u003cfloat:name\u003e`, `\u003cpath:name\u003e`\n- Optional OpenAPI spec + Swagger UI docs (disabled by default)\n- Response coercion:\n  - `str` / `bytes`\n  - `dict` / `list` (JSON)\n  - `(body, status)` / `(body, status, headers)`\n  - `Response`\n\n## Flask-style globals\n\n```python\nfrom flasgo import Flasgo, jsonify, request\n\napp = Flasgo()\n\n\n@app.get(\"/inspect\")\ndef inspect():\n    return jsonify({\"method\": request.method, \"path\": request.path})\n```\n\n## Templating\n\nFlasgo includes a Jinja2 wrapper with secure defaults for HTML rendering:\n\n- Sandboxed environment\n- Strict undefined variables\n- Autoescaping enabled by default\n- Loader protections against path traversal and symlink escapes outside configured template roots\n\nCreate the environment once during app startup and reuse it:\n\n```python\nfrom flasgo import Flasgo, Response\n\napp = Flasgo()\napp.configure_templates(\"templates\")\n\n\n@app.get(\"/\")\ndef home() -\u003e Response:\n    return Response.template(\n        \"home.html\",\n        templates=app.templates,\n        context={\"title\": \"Welcome\"},\n    )\n```\n\nIf you only need the rendered string, use the app helper:\n\n```python\nhtml = app.render_template(\"home.html\", {\"title\": \"Welcome\"})\n```\n\n## Forms\n\nFlasgo has built-in parsing for `application/x-www-form-urlencoded` and `multipart/form-data`:\n\n```python\nfrom flasgo import Flasgo, Request\n\napp = Flasgo()\n\n\n@app.post(\"/signup\")\nasync def signup(request: Request) -\u003e dict[str, object]:\n    form = await request.form()\n    avatar = form.file(\"avatar\")\n    return {\n        \"email\": form.get(\"email\"),\n        \"interests\": form.getlist(\"interests\"),\n        \"avatar_name\": avatar.filename if avatar else None,\n    }\n```\n\n`await request.form()` returns a `FormData` object with `get`, `getlist`, `file`, and `filelist`.\n\nWhen request parsing fails, Flasgo returns actionable `400` responses. For example, invalid JSON from `await request.json()` tells the caller to send valid JSON with `Content-Type: application/json`, and malformed multipart requests explain that the boundary/header is missing.\n\n## Static files\n\nYou can register static assets at app construction time or later:\n\n```python\nfrom flasgo import Flasgo\n\napp = Flasgo(static_folder=\"static\")\napp.configure_static(\"assets\", url_path=\"/assets\", cache_max_age=86400)\n```\n\nStatic responses use safe path normalization, block dotfiles and directory escapes, and include `ETag` and `Last-Modified` headers for cache validation.\n\n## Testing\n\nFlasgo ships with an official test client:\n\n```python\nfrom flasgo import Flasgo\n\n# Testing example only. For browser-facing production apps keep CSRF enabled.\napp = Flasgo(settings={\"CSRF_ENABLED\": False})\nclient = app.test_client()\n\nresponse = client.post(\"/api/login\", json={\"username\": \"alice\"})\nassert response.status_code == 200\n```\n\nThe client supports cookies, `json=`, `data=`, multipart `files=`, `follow_redirects=True`, and async requests via `await client.arequest(...)`.\n\n## Flask migration guide\n\nSee [MIGRATING_FROM_FLASK.md](MIGRATING_FROM_FLASK.md) for the canonical Flask to Flasgo migration guide, including official examples for templates, JSON routes, redirects, forms, static files, testing, and ASGI deployment.\n\n## Django-like settings\n\n```python\napp = Flasgo(\n    settings={\n        \"SECRET_KEY\": \"replace-in-production\",\n        \"ALLOWED_HOSTS\": {\"api.example.com\"},\n        \"CSRF_ENABLED\": True,\n    }\n)\n```\n\nYou can also pass a Python module path string (`\"myproject.settings\"`), and Flasgo will load uppercase settings attributes.\n\n## Auth and permissions\n\n```python\nfrom flasgo import Flasgo, HasScope, IsAuthenticated, User, bearer_token_backend\n\napp = Flasgo()\n\n\ndef validate_token(token: str):\n    if token == \"token-123\":\n        return User(id=\"alice\", is_authenticated=True, scopes=frozenset({\"admin\"}))\n    return None\n\n\napp.register_auth_backend(\"bearer\", bearer_token_backend(validate_token))\n\n\n@app.get(\"/admin\")\n@app.authorize(IsAuthenticated(), HasScope(\"admin\"), backend=\"bearer\")\ndef admin():\n    return \"ok\"\n```\n\nAuth behavior:\n\n- Unauthenticated requests are denied with `401 Unauthorized`.\n- Authenticated requests without permission are denied with `403 Forbidden`.\n- `405 Method Not Allowed` responses include an `Allow` header so clients can retry with a supported method.\n\n## SSRF protection helpers (CWE-918)\n\nFor outbound URLs from user input, resolve a pinned connection target before fetching:\n\n```python\nfrom flasgo import Flasgo\n\napp = Flasgo(\n    settings={\n        \"SSRF_ALLOWED_SCHEMES\": {\"https\"},\n        \"SSRF_ALLOWED_HOSTS\": {\"api.example.com\"},\n    }\n)\n\ntarget = app.resolve_outbound_url(\"https://api.example.com/data\")\n```\n\nBy default, Flasgo blocks unsafe schemes, embedded credentials, localhost/private network targets, and unresolved hosts. Connect to `target.url` and send `target.host_header` as the HTTP `Host` header when your HTTP client supports it.\n\n## Automatic API docs\n\nFlasgo can expose:\n\n- OpenAPI JSON (default path: `/openapi.json`)\n- Swagger UI (default path: `/docs`)\n\nDocs are disabled by default for safer production posture. Enable and customize with settings:\n\n```python\napp = Flasgo(\n    settings={\n        \"ENABLE_DOCS\": True,\n        \"DOCS_PATH\": \"/api-docs\",\n        \"OPENAPI_PATH\": \"/api/openapi.json\",\n        \"API_TITLE\": \"My API\",\n        \"API_VERSION\": \"1.2.3\",\n        \"API_DESCRIPTION\": \"Internal service API\",\n    }\n)\n```\n\nThis is the initial framework baseline; it is intentionally small so the core can evolve quickly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl1ghtn1ng%2Fflasgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fl1ghtn1ng%2Fflasgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl1ghtn1ng%2Fflasgo/lists"}