Repository: sparckles/Robyn Branch: main Commit: 4c3be944961c Files: 346 Total size: 1.1 MB Directory structure: gitextract_zt3t3gjh/ ├── .cargo/ │ └── config ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── blank_issue.md │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── feature_request.md │ ├── dependabot.yml │ ├── pull_request_template.md │ └── workflows/ │ ├── codspeed.yml │ ├── lint-pr.yml │ ├── preview-deployments.yml │ ├── python-CI.yml │ ├── release-CI.yml │ └── rust-CI.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .well-known/ │ └── funding-manifest-urls ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE ├── README.md ├── benchmark.sh ├── ci-local.sh ├── docs_src/ │ ├── .eslintrc.json │ ├── .gitignore │ ├── README.md │ ├── jsconfig.json │ ├── mdx/ │ │ ├── recma.mjs │ │ ├── rehype.mjs │ │ └── remark.mjs │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.js │ ├── prettier.config.js │ ├── public/ │ │ ├── funding.json │ │ └── llms.txt │ ├── src/ │ │ ├── components/ │ │ │ ├── Button.jsx │ │ │ ├── Card.jsx │ │ │ ├── Container.jsx │ │ │ ├── Footer.jsx │ │ │ ├── Header.jsx │ │ │ ├── Prose.jsx │ │ │ ├── Section.jsx │ │ │ ├── SimpleLayout.jsx │ │ │ ├── SocialIcons.jsx │ │ │ ├── Testimonials.jsx │ │ │ ├── documentation/ │ │ │ │ ├── ApiDocs.jsx │ │ │ │ ├── BottomNavbar.jsx │ │ │ │ ├── Button.jsx │ │ │ │ ├── Code.jsx │ │ │ │ ├── Guides.jsx │ │ │ │ ├── Heading.jsx │ │ │ │ ├── HeroPattern.jsx │ │ │ │ ├── LanguageSelector.jsx │ │ │ │ ├── Layout.jsx │ │ │ │ ├── Libraries.jsx │ │ │ │ ├── MobileNavigation.jsx │ │ │ │ ├── ModeToggle.jsx │ │ │ │ ├── Navigation.jsx │ │ │ │ ├── Prose.jsx │ │ │ │ ├── Search.jsx │ │ │ │ ├── SectionProvider.jsx │ │ │ │ ├── Tag.jsx │ │ │ │ ├── icons/ │ │ │ │ │ ├── BellIcon.jsx │ │ │ │ │ ├── BoltIcon.jsx │ │ │ │ │ ├── BookIcon.jsx │ │ │ │ │ ├── CalendarIcon.jsx │ │ │ │ │ ├── CartIcon.jsx │ │ │ │ │ ├── ChatBubbleIcon.jsx │ │ │ │ │ ├── CheckIcon.jsx │ │ │ │ │ ├── ChevronRightLeftIcon.jsx │ │ │ │ │ ├── ClipboardIcon.jsx │ │ │ │ │ ├── CogIcon.jsx │ │ │ │ │ ├── CopyIcon.jsx │ │ │ │ │ ├── DocumentIcon.jsx │ │ │ │ │ ├── EnvelopeIcon.jsx │ │ │ │ │ ├── FaceSmileIcon.jsx │ │ │ │ │ ├── FolderIcon.jsx │ │ │ │ │ ├── LinkIcon.jsx │ │ │ │ │ ├── ListIcon.jsx │ │ │ │ │ ├── MagnifyingGlassIcon.jsx │ │ │ │ │ ├── MapPinIcon.jsx │ │ │ │ │ ├── PackageIcon.jsx │ │ │ │ │ ├── PaperAirplaneIcon.jsx │ │ │ │ │ ├── PaperClipIcon.jsx │ │ │ │ │ ├── ShapesIcon.jsx │ │ │ │ │ ├── ShirtIcon.jsx │ │ │ │ │ ├── SquaresPlusIcon.jsx │ │ │ │ │ ├── TagIcon.jsx │ │ │ │ │ ├── UserIcon.jsx │ │ │ │ │ └── UsersIcon.jsx │ │ │ │ └── mdx.jsx │ │ │ └── releases/ │ │ │ ├── Button.jsx │ │ │ ├── FeedProvider.jsx │ │ │ ├── FormattedDate.jsx │ │ │ ├── IconLink.jsx │ │ │ ├── Intro.jsx │ │ │ ├── Layout.jsx │ │ │ ├── SignUpForm.jsx │ │ │ └── mdx.jsx │ │ ├── lib/ │ │ │ ├── formatDate.js │ │ │ ├── getAllArticles.js │ │ │ └── remToPx.js │ │ ├── pages/ │ │ │ ├── _app.jsx │ │ │ ├── _document.jsx │ │ │ ├── community.jsx │ │ │ ├── documentation/ │ │ │ │ ├── en/ │ │ │ │ │ ├── api_reference/ │ │ │ │ │ │ ├── advanced_features.mdx │ │ │ │ │ │ ├── advanced_routing.mdx │ │ │ │ │ │ ├── agents.mdx │ │ │ │ │ │ ├── ai.mdx │ │ │ │ │ │ ├── architecture_deep_dive.mdx │ │ │ │ │ │ ├── authentication.mdx │ │ │ │ │ │ ├── const_requests.mdx │ │ │ │ │ │ ├── cors.mdx │ │ │ │ │ │ ├── dependency_injection.mdx │ │ │ │ │ │ ├── exceptions.mdx │ │ │ │ │ │ ├── file-uploads.mdx │ │ │ │ │ │ ├── form_data.mdx │ │ │ │ │ │ ├── future-roadmap.mdx │ │ │ │ │ │ ├── getting_started.mdx │ │ │ │ │ │ ├── graphql-support.mdx │ │ │ │ │ │ ├── index.mdx │ │ │ │ │ │ ├── mcps.mdx │ │ │ │ │ │ ├── middlewares.mdx │ │ │ │ │ │ ├── multiprocess_execution.mdx │ │ │ │ │ │ ├── openapi.mdx │ │ │ │ │ │ ├── pydantic.mdx │ │ │ │ │ │ ├── redirection.mdx │ │ │ │ │ │ ├── request_object.mdx │ │ │ │ │ │ ├── robyn_env.mdx │ │ │ │ │ │ ├── scaling.mdx │ │ │ │ │ │ ├── server_sent_events.mdx │ │ │ │ │ │ ├── templating.mdx │ │ │ │ │ │ ├── timeout_configuration.mdx │ │ │ │ │ │ ├── using_rust_directly.mdx │ │ │ │ │ │ ├── websockets.mdx │ │ │ │ │ │ └── zh/ │ │ │ │ │ │ └── getting_started.mdx │ │ │ │ │ ├── architecture.mdx │ │ │ │ │ ├── community-resources.mdx │ │ │ │ │ ├── example_app/ │ │ │ │ │ │ ├── authentication-middlewares.mdx │ │ │ │ │ │ ├── authentication.mdx │ │ │ │ │ │ ├── deployment.mdx │ │ │ │ │ │ ├── index.mdx │ │ │ │ │ │ ├── modeling_routes.mdx │ │ │ │ │ │ ├── monitoring_and_logging.mdx │ │ │ │ │ │ ├── openapi.mdx │ │ │ │ │ │ ├── real_time_notifications.mdx │ │ │ │ │ │ ├── subrouters.mdx │ │ │ │ │ │ ├── templates.mdx │ │ │ │ │ │ └── zh/ │ │ │ │ │ │ ├── index.mdx │ │ │ │ │ │ └── subrouters.mdx │ │ │ │ │ ├── framework_performance_comparison.mdx │ │ │ │ │ ├── hosting.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ └── plugins.mdx │ │ │ │ └── zh/ │ │ │ │ ├── api_reference/ │ │ │ │ │ ├── advanced_features.mdx │ │ │ │ │ ├── authentication.mdx │ │ │ │ │ ├── const_requests.mdx │ │ │ │ │ ├── cors.mdx │ │ │ │ │ ├── dependency_injection.mdx │ │ │ │ │ ├── exceptions.mdx │ │ │ │ │ ├── file-uploads.mdx │ │ │ │ │ ├── form_data.mdx │ │ │ │ │ ├── future-roadmap.mdx │ │ │ │ │ ├── getting_started.mdx │ │ │ │ │ ├── graphql-support.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ ├── middlewares.mdx │ │ │ │ │ ├── multiprocess_execution.mdx │ │ │ │ │ ├── openapi.mdx │ │ │ │ │ ├── pydantic.mdx │ │ │ │ │ ├── redirection.mdx │ │ │ │ │ ├── request_object.mdx │ │ │ │ │ ├── robyn_env.mdx │ │ │ │ │ ├── scaling.mdx │ │ │ │ │ ├── server_sent_events.mdx │ │ │ │ │ ├── templating.mdx │ │ │ │ │ ├── timeout_configuration.mdx │ │ │ │ │ ├── using_rust_directly.mdx │ │ │ │ │ ├── views.mdx │ │ │ │ │ └── websockets.mdx │ │ │ │ ├── architecture.mdx │ │ │ │ ├── community-resources.mdx │ │ │ │ ├── example_app/ │ │ │ │ │ ├── authentication-middlewares.mdx │ │ │ │ │ ├── authentication.mdx │ │ │ │ │ ├── deployment.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ ├── modeling_routes.mdx │ │ │ │ │ ├── monitoring_and_logging.mdx │ │ │ │ │ ├── openapi.mdx │ │ │ │ │ ├── real_time_notifications.mdx │ │ │ │ │ ├── subrouters_and_views.mdx │ │ │ │ │ └── templates.mdx │ │ │ │ ├── framework_performance_comparison.mdx │ │ │ │ ├── hosting.mdx │ │ │ │ ├── index.mdx │ │ │ │ └── plugins.mdx │ │ │ ├── index.jsx │ │ │ └── releases/ │ │ │ └── index.jsx │ │ └── styles/ │ │ ├── documentation.css │ │ ├── prism.css │ │ ├── releases/ │ │ │ ├── base.css │ │ │ ├── components.css │ │ │ ├── tailwind.css │ │ │ ├── typography.css │ │ │ └── utilities.css │ │ └── tailwind.css │ └── tailwind.config.js ├── examples/ │ ├── agents.py │ ├── mcp.py │ └── sse_example.py ├── integration_tests/ │ ├── __init__.py │ ├── base_routes.py │ ├── build/ │ │ └── index.html │ ├── conftest.py │ ├── downloads/ │ │ └── test.txt │ ├── helpers/ │ │ ├── __init__.py │ │ ├── http_methods_helpers.py │ │ └── network_helpers.py │ ├── index.html │ ├── index.py │ ├── openapi_config.json │ ├── random_number.rs │ ├── subroutes/ │ │ ├── __init__.py │ │ ├── di_subrouter.py │ │ └── file_api.py │ ├── templates/ │ │ └── test.html │ ├── test_add_route_without_decorator.py │ ├── test_app.py │ ├── test_authentication.py │ ├── test_base_url.py │ ├── test_basic_routes.py │ ├── test_binary_output.py │ ├── test_delete_requests.py │ ├── test_dependency_injection.py │ ├── test_easy_access_params.py │ ├── test_exception_handling.py │ ├── test_file_download.py │ ├── test_get_requests.py │ ├── test_json_types.py │ ├── test_middlewares.py │ ├── test_multipart_data.py │ ├── test_openapi.py │ ├── test_patch_requests.py │ ├── test_post_requests.py │ ├── test_put_requests.py │ ├── test_pydantic.py │ ├── test_request_json.py │ ├── test_split_request_params.py │ ├── test_sse.py │ ├── test_static_files_with_api_routes.py │ ├── test_status_code.py │ ├── test_subrouter.py │ └── test_web_sockets.py ├── llms.txt ├── noxfile.py ├── pyproject.toml ├── robyn/ │ ├── __init__.py │ ├── __main__.py │ ├── _param_utils.py │ ├── ai.py │ ├── argument_parser.py │ ├── authentication.py │ ├── cli.py │ ├── dependency_injection.py │ ├── env_populator.py │ ├── events.py │ ├── exceptions.py │ ├── jsonify.py │ ├── logger.py │ ├── mcp.py │ ├── openapi.py │ ├── processpool.py │ ├── py.typed │ ├── pydantic_support.py │ ├── reloader.py │ ├── responses.py │ ├── robyn.pyi │ ├── router.py │ ├── scaffold/ │ │ ├── mongo/ │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ ├── no-db/ │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ ├── postgres/ │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ ├── requirements.txt │ │ │ └── supervisord.conf │ │ ├── prisma/ │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ ├── requirements.txt │ │ │ └── schema.prisma │ │ ├── sqlalchemy/ │ │ │ ├── Dockerfile │ │ │ ├── __init__.py │ │ │ ├── app.py │ │ │ ├── models.py │ │ │ └── requirements.txt │ │ ├── sqlite/ │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ └── requirements.txt │ │ └── sqlmodel/ │ │ ├── Dockerfile │ │ ├── app.py │ │ ├── models.py │ │ └── requirements.txt │ ├── status_codes.py │ ├── swagger.html │ ├── templating.py │ ├── types.py │ └── ws.py ├── scripts/ │ ├── format.sh │ └── release.sh ├── setup.py ├── src/ │ ├── asyncio.rs │ ├── blocking.rs │ ├── callbacks.rs │ ├── conversion.rs │ ├── executors/ │ │ ├── mod.rs │ │ └── web_socket_executors.rs │ ├── io_helpers/ │ │ └── mod.rs │ ├── lib.rs │ ├── routers/ │ │ ├── const_router.rs │ │ ├── http_router.rs │ │ ├── middleware_router.rs │ │ ├── mod.rs │ │ └── web_socket_router.rs │ ├── runtime.rs │ ├── server.rs │ ├── shared_socket.rs │ ├── types/ │ │ ├── cookie.rs │ │ ├── function_info.rs │ │ ├── headers.rs │ │ ├── identity.rs │ │ ├── mod.rs │ │ ├── multimap.rs │ │ ├── request.rs │ │ └── response.rs │ └── websockets/ │ ├── mod.rs │ └── registry.rs └── unit_tests/ ├── test_cli.py ├── test_env_populator.py ├── test_openapi_issue_1270.py ├── test_request_object.py └── test_unsupported_types.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .cargo/config ================================================ [target.x86_64-apple-darwin] rustflags = [ "-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup", ] [target.aarch64-apple-darwin] rustflags = [ "-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup", ] ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [sansyrox] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] #patreon: # Replace with a single Patreon username open_collective: robyn_oss # Replace with a single Open Collective username #ko_fi: # Replace with a single Ko-fi username #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry # liberapay: # Replace with a single Liberapay username # issuehunt: # Replace with a single IssueHunt username # otechie: # Replace with a single Otechie username # lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] ================================================ FILE: .github/ISSUE_TEMPLATE/blank_issue.md ================================================ --- name: 📝 Blank Issue about: Create a blank issue. --- ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: 🐛 Bug Report description: Create a bug report labels: [bug] body: - type: markdown attributes: value: | Thank you for taking the time to fill out this bug report! Please fill out the form below... - type: textarea id: description attributes: label: Bug Description description: Please provide a clear and concise description of what the bug is, and what you would expect to happen. placeholder: The bug is... validations: required: true - type: textarea id: reproduce attributes: label: Steps to Reproduce description: Please provide the steps to reproduce this bug. You can include your code here if it is relevant. placeholder: | 1. 2. 3. validations: required: false - type: dropdown id: os attributes: label: Your operating system options: - Windows - MacOS - Linux - Other (specify below) validations: required: false - type: dropdown id: py_version attributes: label: Your Python version (`python --version`) options: - 3.9 - 3.10 - 3.11 - 3.12 - 3.13 - Other (specify below) validations: required: false - type: dropdown id: robyn_version attributes: label: Your Robyn version options: - main branch - latest - Other (specify below) validations: required: false - type: textarea id: additional-info attributes: label: Additional Info description: Any additional info that you think might be useful or relevant to this bug ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: true contact_links: - name: Discord Community Support url: https://discord.gg/rkERZ5eNU8 about: You can ask and answer questions here. - name: Documentation url: https://robyn.tech about: The Robyn documentation. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: 💡 Feature request about: Suggest an idea to improve Robyn labels: [enhancement] --- ================================================ FILE: .github/dependabot.yml ================================================ # Keep GitHub Actions up to date with GitHub's Dependabot... # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem version: 2 updates: - package-ecosystem: github-actions directory: / groups: github-actions: patterns: - "*" # Group all Actions updates into a single larger pull request schedule: interval: weekly ================================================ FILE: .github/pull_request_template.md ================================================ ## Description This PR fixes # ## Summary This PR does.... ## PR Checklist Please ensure that: - [ ] The PR contains a descriptive title - [ ] The PR contains a descriptive summary of the changes - [ ] You build and test your changes before submitting a PR. - [ ] You have added relevant documentation - [ ] You have added relevant tests. We prefer integration tests wherever possible ## Pre-Commit Instructions: - [ ] Ensure that you have run the [pre-commit hooks](https://github.com/sparckles/robyn#%EF%B8%8F-to-develop-locally) on your PR. ================================================ FILE: .github/workflows/codspeed.yml ================================================ name: codspeed-benchmarks on: push: branches: - "main" # or "master" pull_request: # `workflow_dispatch` allows CodSpeed to trigger backtest # performance analysis in order to generate initial data. workflow_dispatch: jobs: benchmarks: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v6 with: python-version: "3.10" - name: Install uv uses: astral-sh/setup-uv@v6 with: version: "0.7.5" - name: Install the project + deps. run: | echo "# Syncing Project + Installing project." uv sync --dev --group test --verbose - name: Run benchmarks uses: CodSpeedHQ/action@v3.5.0 with: token: ${{ secrets.CODSPEED_TOKEN }} run: uv run pytest integration_tests --codspeed ================================================ FILE: .github/workflows/lint-pr.yml ================================================ name: Lint PR on: pull_request: branches: [main] env: UV_SYSTEM_PYTHON: 1 jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: "3.11" - name: Install dependencies with uv run: | uv pip install ruff isort black - name: Run linters run: | uv run ruff check . uv run isort --check-only --diff . ================================================ FILE: .github/workflows/preview-deployments.yml ================================================ # CI to release the project for Linux, Windows, and MacOS # The purpose of this action is to verify if the release builds are working or not. name: Preview Release on: push: branches: - main pull_request: branches: - main env: UV_SYSTEM_PYTHON: 1 jobs: macos: runs-on: macos-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - uses: dtolnay/rust-toolchain@stable with: targets: aarch64-apple-darwin - name: Build wheels - x86_64 uses: PyO3/maturin-action@v1 with: target: x86_64 args: -i python --release --out dist - name: Build wheels - universal2 uses: PyO3/maturin-action@v1 with: target: universal2-apple-darwin args: -i python --release --out dist - name: Install build wheel - universal2 run: | uv pip install --force-reinstall dist/robyn*_universal2.whl cd ~ && python -c 'import robyn' windows: runs-on: windows-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] target: [x64, x86] steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} architecture: ${{ matrix.target }} - uses: dtolnay/rust-toolchain@stable - name: Build wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.target }} args: -i python --release --out dist - name: Install build wheel shell: bash run: | uv pip install --force-reinstall dist/robyn*.whl cd ~ && python -c 'import robyn' linux: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] target: [x86_64, i686] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Build Wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.target }} manylinux: auto args: -i python${{ matrix.python-version }} --release --out dist - name: Install build wheel if: matrix.target == 'x86_64' run: | uv pip install --force-reinstall dist/robyn*.whl cd ~ && python -c 'import robyn' linux-cross: runs-on: ubuntu-latest strategy: fail-fast: false matrix: python: [ { version: "3.10", abi: "cp310-cp310" }, { version: "3.11", abi: "cp311-cp311" }, { version: "3.12", abi: "cp312-cp312" }, { version: "3.13", abi: "cp313-cp313" }, { version: "3.14", abi: "cp314-cp314" }, ] target: [aarch64, armv7] steps: - uses: actions/checkout@v3 - name: Build Wheels uses: PyO3/maturin-action@v1 env: PYO3_CROSS_LIB_DIR: /opt/python/${{ matrix.python.abi }}/lib with: target: ${{ matrix.target }} manylinux: auto args: -i python${{matrix.python.version}} --release --out dist - uses: uraimo/run-on-arch-action@v2 name: Install build wheel with: arch: ${{ matrix.target }} distro: ubuntu22.04 githubToken: ${{ github.token }} # Mount the dist directory as /artifacts in the container dockerRunArgs: | --volume "${PWD}/dist:/artifacts" install: | apt update -y apt install -y software-properties-common add-apt-repository -y ppa:deadsnakes/ppa apt update -y apt install -y gcc musl-dev python3-dev python${{ matrix.python.version }} python${{ matrix.python.version }}-venv run: | ls -lrth /artifacts python${{ matrix.python.version }} -m venv venv source venv/bin/activate python -m pip install --upgrade pip setuptools wheel python -m pip install --force-reinstall /artifacts/robyn*.whl cd ~ && python -c 'import robyn' ================================================ FILE: .github/workflows/python-CI.yml ================================================ # CI to test Robyn on major Linux, MacOS and Windows on: [push, pull_request] name: Python Continuous integration jobs: tests: strategy: fail-fast: false matrix: os: ["windows", "ubuntu", "macos"] python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] name: ${{ matrix.os }} tests with python ${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Set up Nox uses: wntrblm/nox@2024.03.02 with: python-versions: ${{ matrix.python-version }} - name: Test with Nox run: nox --non-interactive --error-on-missing-interpreter -p ${{ matrix.python-version }} ================================================ FILE: .github/workflows/release-CI.yml ================================================ # CI to release the project for Linux, Windows, and MacOS name: Release CI on: push: tags: - v* workflow_dispatch: inputs: enable_linux_cross: description: 'Enable Linux cross-compilation (ARM64/ARMv7)' required: false default: true type: boolean env: UV_SYSTEM_PYTHON: 1 jobs: macos: runs-on: macos-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v3 - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - uses: dtolnay/rust-toolchain@stable with: targets: aarch64-apple-darwin - name: Build wheels - x86_64 uses: PyO3/maturin-action@v1 with: target: x86_64 args: -i python --release --out dist - name: Build wheels - universal2 uses: PyO3/maturin-action@v1 with: target: universal2-apple-darwin args: -i python --release --out dist - name: Install build wheel - universal2 run: | uv pip install --force-reinstall dist/robyn*_universal2.whl cd ~ && python -c 'import robyn' - name: Upload wheels uses: actions/upload-artifact@v4 with: name: wheels-${{ github.job }}-universal-${{ matrix.python-version }} path: dist windows: runs-on: windows-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] target: [x64, x86] steps: - uses: actions/checkout@v3 - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} architecture: ${{ matrix.target }} - uses: dtolnay/rust-toolchain@stable - name: Build wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.target }} args: -i python --release --out dist - name: Install build wheel shell: bash run: | uv pip install --force-reinstall dist/robyn*.whl cd ~ && python -c 'import robyn' - name: Upload wheels uses: actions/upload-artifact@v4 with: name: wheels-${{ github.job }}-${{ matrix.target }}-${{ matrix.python-version }} path: dist linux: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] target: [x86_64, i686] steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Build Wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.target }} manylinux: auto args: -i python${{ matrix.python-version }} --release --out dist - name: Install build wheel if: matrix.target == 'x86_64' run: | uv pip install --force-reinstall dist/robyn*.whl cd ~ && python -c 'import robyn' - name: Upload wheels uses: actions/upload-artifact@v4 with: name: wheels-${{ github.job }}-${{ matrix.target }}-${{ matrix.python-version }} path: dist linux-cross: runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.enable_linux_cross) strategy: matrix: python: [ { version: "3.10", abi: "cp310-cp310" }, { version: "3.11", abi: "cp311-cp311" }, { version: "3.12", abi: "cp312-cp312" }, { version: "3.13", abi: "cp313-cp313" }, ] target: [aarch64, armv7] steps: - uses: actions/checkout@v3 - name: Build Wheels uses: PyO3/maturin-action@v1 env: PYO3_CROSS_LIB_DIR: /opt/python/${{ matrix.python.abi }}/lib with: target: ${{ matrix.target }} manylinux: auto maturin-version: "v1.12.0" args: -i python${{matrix.python.version}} --release --out dist - uses: uraimo/run-on-arch-action@v2 name: Install build wheel with: arch: ${{ matrix.target }} distro: ubuntu22.04 githubToken: ${{ github.token }} # Mount the dist directory as /artifacts in the container dockerRunArgs: | --volume "${PWD}/dist:/artifacts" install: | apt update -y apt install -y software-properties-common add-apt-repository -y ppa:deadsnakes/ppa apt update -y apt install -y gcc musl-dev python3-dev python${{ matrix.python.version }} python${{ matrix.python.version }}-venv run: | ls -lrth /artifacts python${{ matrix.python.version }} -m venv venv source venv/bin/activate python -m pip install --upgrade pip setuptools wheel python -m pip install --force-reinstall /artifacts/robyn*.whl cd ~ && python -c 'import robyn' - name: Upload wheels uses: actions/upload-artifact@v4 with: name: wheels-${{ github.job }}-${{ matrix.target }}-${{ matrix.python.version }}-${{ matrix.python.abi }} path: dist merge: name: Building Single Artifact runs-on: ubuntu-latest needs: [macos, windows, linux, linux-cross] if: always() && needs.macos.result == 'success' && needs.windows.result == 'success' && needs.linux.result == 'success' && (needs.linux-cross.result == 'success' || needs.linux-cross.result == 'skipped') steps: - name: Downloading all Artifacts uses: actions/download-artifact@v4 with: path: artifacts pattern: wheels-* merge-multiple: true - run: | echo "Listing directories" ls -R - name: Uploading Artifact's Bundle uses: actions/upload-artifact@v4 with: name: wheels path: artifacts release: name: Release runs-on: ubuntu-latest needs: [macos, windows, linux, linux-cross, merge] if: always() && needs.merge.result == 'success' steps: - uses: actions/download-artifact@v4 with: name: wheels - name: Install uv uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v6 with: python-version: 3.x - name: Publish to PyPi env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | uv pip install --upgrade twine twine upload --skip-existing *.whl ================================================ FILE: .github/workflows/rust-CI.yml ================================================ # CI to build, test, format, and lint the Rust code on: [push, pull_request] name: Rust Continuous integration jobs: check: name: Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: cargo check test: name: Test Suite runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: cargo test fmt: name: Rustfmt runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: rustfmt - run: cargo fmt --check clippy: name: Clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: clippy - run: cargo clippy # -- -D warnings ================================================ FILE: .gitignore ================================================ .python-version /target # ignore pre compiled binaries *.so dist/ #python cache *__pycache__ *tags # DS_Store *.DS_Store .vscode # pycharm .idea # python venv .venv venv robyn.code-workspace hello_robyn.py robyn.env # nox .nox/ # new docs dependencies # dependencies docs_src/node_modules docs_src/.pnp docs_src/.pnp.js # testing docs_src/coverage # next.js docs_src/.next/ docs_src/out/ # production docs_src/build # misc docs_src/.DS_Store docs_src/*.pem # debug docs_src/npm-debug.log* docs_src/yarn-debug.log* docs_src/yarn-error.log* docs_src/.pnpm-debug.log* # local env files docs_src/.env*.local # vercel docs_src/.vercel # generated files docs_src/public/rss/ #https://github.com/PyO3/maturin/issues/2141 *.pyd ================================================ FILE: .pre-commit-config.yaml ================================================ repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.13 hooks: - id: ruff args: - --fix - id: ruff-format ci: autoupdate_schedule: weekly ================================================ FILE: .well-known/funding-manifest-urls ================================================ https://robyn.tech/funding.json ================================================ FILE: CHANGELOG.md ================================================ # Changelog ## [Unreleased](https://github.com/sparckles/robyn/tree/HEAD) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.26.1...HEAD) **Implemented enhancements:** - Allow empty returns on websocket handling [\#1263](https://github.com/sparckles/robyn/issues/1263) **Closed issues:** - Payload reached size limit. [\#463](https://github.com/sparckles/robyn/issues/463) - Proposal to rename `params` with `path_params` [\#457](https://github.com/sparckles/robyn/issues/457) **Merged pull requests:** - feat: allow configurable payload sizes [\#465](https://github.com/sparckles/robyn/pull/465) ([sansyrox](https://github.com/sansyrox)) - docs: remove test pypi instructions from pr template [\#462](https://github.com/sparckles/robyn/pull/462) ([sansyrox](https://github.com/sansyrox)) - Rename params with path\_params [\#460](https://github.com/sparckles/robyn/pull/460) ([carlosm27](https://github.com/carlosm27)) - feat: Implement global CORS [\#458](https://github.com/sparckles/robyn/pull/458) ([sansyrox](https://github.com/sansyrox)) ## [v0.26.1](https://github.com/sparckles/robyn/tree/v0.26.1) (2023-04-05) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.26.0...v0.26.1) **Fixed bugs:** - Can't access new or updated route while on dev option [\#439](https://github.com/sparckles/robyn/issues/439) **Closed issues:** - Add documentation for `robyn.env` file [\#454](https://github.com/sparckles/robyn/issues/454) **Merged pull requests:** - Release v0.26.1 [\#461](https://github.com/sparckles/robyn/pull/461) ([sansyrox](https://github.com/sansyrox)) - \[pre-commit.ci\] pre-commit autoupdate [\#459](https://github.com/sparckles/robyn/pull/459) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - \[pre-commit.ci\] pre-commit autoupdate [\#452](https://github.com/sparckles/robyn/pull/452) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - docs: Add docs for v0.26.0 [\#451](https://github.com/sparckles/robyn/pull/451) ([sansyrox](https://github.com/sansyrox)) - fix\(dev\): fix hot reloading with dev flag [\#446](https://github.com/sparckles/robyn/pull/446) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.26.0](https://github.com/sparckles/robyn/tree/v0.26.0) (2023-03-24) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.25.0...v0.26.0) **Implemented enhancements:** - \[Feature Request\] Robyn providing Status Codes? [\#423](https://github.com/sparckles/robyn/issues/423) - \[Feature Request\] Allow global level Response headers [\#335](https://github.com/sparckles/robyn/issues/335) **Fixed bugs:** - \[BUG\] `uvloop` ModuleNotFoundError: No module named 'uvloop' on Ubuntu Docker Image [\#395](https://github.com/sparckles/robyn/issues/395) **Closed issues:** - \[Feature Request\] When Robyn can have a middleware mechanism like flask or django [\#350](https://github.com/sparckles/robyn/issues/350) - Forced shutdown locks console. \[BUG\] [\#317](https://github.com/sparckles/robyn/issues/317) **Merged pull requests:** - \[pre-commit.ci\] pre-commit autoupdate [\#449](https://github.com/sparckles/robyn/pull/449) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - fix: Implement auto installation of uvloop on linux arm [\#445](https://github.com/sparckles/robyn/pull/445) ([sansyrox](https://github.com/sansyrox)) - chore: update rust dependencies [\#444](https://github.com/sparckles/robyn/pull/444) ([AntoineRR](https://github.com/AntoineRR)) - feat: Implement performance benchmarking [\#443](https://github.com/sparckles/robyn/pull/443) ([sansyrox](https://github.com/sansyrox)) - feat: expose request/connection info [\#441](https://github.com/sparckles/robyn/pull/441) ([r3b-fish](https://github.com/r3b-fish)) - Install the CodeSee workflow. [\#438](https://github.com/sparckles/robyn/pull/438) ([codesee-maps[bot]](https://github.com/apps/codesee-maps)) - \[pre-commit.ci\] pre-commit autoupdate [\#437](https://github.com/sparckles/robyn/pull/437) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - Replace integer status codes with Enum values of StatusCodes [\#436](https://github.com/sparckles/robyn/pull/436) ([Noborita9](https://github.com/Noborita9)) - added `star-history` [\#434](https://github.com/sparckles/robyn/pull/434) ([hemangjoshi37a](https://github.com/hemangjoshi37a)) - \[pre-commit.ci\] pre-commit autoupdate [\#433](https://github.com/sparckles/robyn/pull/433) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - feat: Robyn providing status codes [\#429](https://github.com/sparckles/robyn/pull/429) ([carlosm27](https://github.com/carlosm27)) - feat: Allow global level Response headers [\#410](https://github.com/sparckles/robyn/pull/410) ([ParthS007](https://github.com/ParthS007)) - feat: get rid of intermediate representations of requests and responses [\#397](https://github.com/sparckles/robyn/pull/397) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.25.0](https://github.com/sparckles/robyn/tree/v0.25.0) (2023-02-20) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.24.1...v0.25.0) **Implemented enhancements:** - using robyn with some frameworks [\#420](https://github.com/sparckles/robyn/issues/420) **Fixed bugs:** - Template Rendering is not working in some browsers [\#426](https://github.com/sparckles/robyn/issues/426) **Closed issues:** - \[Feature Request\] Show support for Python versions in the README [\#396](https://github.com/sparckles/robyn/issues/396) - \[BUG\] The dev flag doesn't set the log level to DEBUG [\#385](https://github.com/sparckles/robyn/issues/385) - \[BUG\] All tests are not passing on windows [\#372](https://github.com/sparckles/robyn/issues/372) - \[Feature Request\] Add views/view controllers [\#221](https://github.com/sparckles/robyn/issues/221) **Merged pull requests:** - fix: Add proper headers to the templates return types [\#427](https://github.com/sparckles/robyn/pull/427) ([sansyrox](https://github.com/sansyrox)) - \[pre-commit.ci\] pre-commit autoupdate [\#425](https://github.com/sparckles/robyn/pull/425) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - docs: Add documentation for views [\#424](https://github.com/sparckles/robyn/pull/424) ([sansyrox](https://github.com/sansyrox)) - better way to compare type [\#421](https://github.com/sparckles/robyn/pull/421) ([jmishra01](https://github.com/jmishra01)) - style\(landing\_page\): fix the style of github logo on the landing page [\#419](https://github.com/sparckles/robyn/pull/419) ([sansyrox](https://github.com/sansyrox)) - docs: improve readme [\#418](https://github.com/sparckles/robyn/pull/418) ([AntoineRR](https://github.com/AntoineRR)) - docs: add dark mode to website [\#416](https://github.com/sparckles/robyn/pull/416) ([AntoineRR](https://github.com/AntoineRR)) - chore: improve issue templates [\#413](https://github.com/sparckles/robyn/pull/413) ([AntoineRR](https://github.com/AntoineRR)) - \[pre-commit.ci\] pre-commit autoupdate [\#412](https://github.com/sparckles/robyn/pull/412) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - fix: fixed CONTRIBUTE.md link into docs/README.md file, changing it f… [\#411](https://github.com/sparckles/robyn/pull/411) ([Kop3sh](https://github.com/Kop3sh)) - chore\(ci\): fix rust ci warnings [\#408](https://github.com/sparckles/robyn/pull/408) ([AntoineRR](https://github.com/AntoineRR)) - feat: Add view controllers [\#407](https://github.com/sparckles/robyn/pull/407) ([mikaeelghr](https://github.com/mikaeelghr)) - Fix docs: support version [\#404](https://github.com/sparckles/robyn/pull/404) ([Oluwaseun241](https://github.com/Oluwaseun241)) - fix: Fix Windows tests [\#402](https://github.com/sparckles/robyn/pull/402) ([sansyrox](https://github.com/sansyrox)) - docs: Update PyPi metadata [\#401](https://github.com/sparckles/robyn/pull/401) ([sansyrox](https://github.com/sansyrox)) - fix\(test\): fix tests on windows [\#400](https://github.com/sparckles/robyn/pull/400) ([AntoineRR](https://github.com/AntoineRR)) - fix: various improvements around the dev flag [\#388](https://github.com/sparckles/robyn/pull/388) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.24.1](https://github.com/sparckles/robyn/tree/v0.24.1) (2023-02-09) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.24.0...v0.24.1) **Closed issues:** - \[BUG\] \[Windows\] Terminal hanging after Ctrl+C is pressed on Robyn server [\#373](https://github.com/sparckles/robyn/issues/373) **Merged pull requests:** - \[pre-commit.ci\] pre-commit autoupdate [\#394](https://github.com/sparckles/robyn/pull/394) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - docs: add documentation regarding byte response [\#392](https://github.com/sparckles/robyn/pull/392) ([sansyrox](https://github.com/sansyrox)) - fix: fix terminal hijacking in windows [\#391](https://github.com/sparckles/robyn/pull/391) ([sansyrox](https://github.com/sansyrox)) - chore: fix requirements files and update packages [\#389](https://github.com/sparckles/robyn/pull/389) ([AntoineRR](https://github.com/AntoineRR)) - small correction in docs [\#387](https://github.com/sparckles/robyn/pull/387) ([tkanhe](https://github.com/tkanhe)) - \[pre-commit.ci\] pre-commit autoupdate [\#384](https://github.com/sparckles/robyn/pull/384) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - ci: build artifacts on every push and pull [\#378](https://github.com/sparckles/robyn/pull/378) ([sansyrox](https://github.com/sansyrox)) - test: organize and add tests [\#377](https://github.com/sparckles/robyn/pull/377) ([AntoineRR](https://github.com/AntoineRR)) - Changed Response to use body: bytes [\#375](https://github.com/sparckles/robyn/pull/375) ([madhavajay](https://github.com/madhavajay)) ## [v0.24.0](https://github.com/sparckles/robyn/tree/v0.24.0) (2023-02-06) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.23.1...v0.24.0) **Closed issues:** - \[BUG\] Release builds are not working [\#386](https://github.com/sparckles/robyn/issues/386) - \[BUG\] Can't send raw bytes [\#374](https://github.com/sparckles/robyn/issues/374) ## [v0.23.1](https://github.com/sparckles/robyn/tree/v0.23.1) (2023-01-30) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.23.0...v0.23.1) **Closed issues:** - \[BUG\] Return 500 status code when route is raising [\#381](https://github.com/sparckles/robyn/issues/381) - \[BUG\] Return 404 status code when route isn't set [\#376](https://github.com/sparckles/robyn/issues/376) - Add Appwrite as a sponsor in the README [\#348](https://github.com/sparckles/robyn/issues/348) - \[BUG\] Get Stared failed on Windows [\#340](https://github.com/sparckles/robyn/issues/340) - \[BUG\] Fix CI/CD pipeline [\#310](https://github.com/sparckles/robyn/issues/310) **Merged pull requests:** - chore\(ci\): fix robyn installation in test CI [\#383](https://github.com/sparckles/robyn/pull/383) ([AntoineRR](https://github.com/AntoineRR)) - fix: return 500 status code when route raise [\#382](https://github.com/sparckles/robyn/pull/382) ([AntoineRR](https://github.com/AntoineRR)) - fix: return 404 status code when route isn't found [\#380](https://github.com/sparckles/robyn/pull/380) ([AntoineRR](https://github.com/AntoineRR)) - ci: enable precommit hooks on everything [\#371](https://github.com/sparckles/robyn/pull/371) ([sansyrox](https://github.com/sansyrox)) - chore: run tests on linux, macos and windows and release builds on ta… [\#370](https://github.com/sparckles/robyn/pull/370) ([AntoineRR](https://github.com/AntoineRR)) - docs: add appwrite logo as sponsors [\#369](https://github.com/sparckles/robyn/pull/369) ([sansyrox](https://github.com/sansyrox)) - test: improve pytest fixtures [\#368](https://github.com/sparckles/robyn/pull/368) ([AntoineRR](https://github.com/AntoineRR)) - Move pre-commit hooks to use Ruff [\#364](https://github.com/sparckles/robyn/pull/364) ([patrick91](https://github.com/patrick91)) ## [v0.23.0](https://github.com/sparckles/robyn/tree/v0.23.0) (2023-01-21) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.22.1...v0.23.0) **Closed issues:** - \[Feature Request\] Improve the release and testing pipeline [\#341](https://github.com/sparckles/robyn/issues/341) **Merged pull requests:** - ci: delete the test pypi workflow [\#367](https://github.com/sparckles/robyn/pull/367) ([sansyrox](https://github.com/sansyrox)) - docs: Add page icon to index page [\#365](https://github.com/sparckles/robyn/pull/365) ([Abdur-rahmaanJ](https://github.com/Abdur-rahmaanJ)) - test: speed up tests [\#362](https://github.com/sparckles/robyn/pull/362) ([AntoineRR](https://github.com/AntoineRR)) - Replace the default port with 8080 [\#352](https://github.com/sparckles/robyn/pull/352) ([sansyrox](https://github.com/sansyrox)) ## [v0.22.1](https://github.com/sparckles/robyn/tree/v0.22.1) (2023-01-16) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.22.0...v0.22.1) **Closed issues:** - \[BUG\] Python 3.11 error: metadata-generation-failed [\#357](https://github.com/sparckles/robyn/issues/357) **Merged pull requests:** - ci: update precommit config [\#361](https://github.com/sparckles/robyn/pull/361) ([sansyrox](https://github.com/sansyrox)) - \[pre-commit.ci\] pre-commit autoupdate [\#359](https://github.com/sparckles/robyn/pull/359) ([pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci)) - chore\(ci\): add python 3.11 to the build and test CI [\#358](https://github.com/sparckles/robyn/pull/358) ([AntoineRR](https://github.com/AntoineRR)) - Updates prose to format code block and docs [\#356](https://github.com/sparckles/robyn/pull/356) ([rachfop](https://github.com/rachfop)) ## [v0.22.0](https://github.com/sparckles/robyn/tree/v0.22.0) (2023-01-14) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.21.0...v0.22.0) **Closed issues:** - AttributeError: 'Robyn' object has no attribute 'headers'\[BUG\] [\#353](https://github.com/sparckles/robyn/issues/353) - \[Feature Request\] Allow support for multiple file types [\#344](https://github.com/sparckles/robyn/issues/344) - \[Feature Request\] Investigate if we need an unit tests for Python functions created in Rust [\#311](https://github.com/sparckles/robyn/issues/311) - \[Experimental Feature Request\] Story driven programming [\#258](https://github.com/sparckles/robyn/issues/258) **Merged pull requests:** - fix: windows support [\#354](https://github.com/sparckles/robyn/pull/354) ([sansyrox](https://github.com/sansyrox)) - fix: better handling of route return type [\#349](https://github.com/sparckles/robyn/pull/349) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.21.0](https://github.com/sparckles/robyn/tree/v0.21.0) (2023-01-06) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.20.0...v0.21.0) **Closed issues:** - \[Feature Request\] Support for image file type [\#343](https://github.com/sparckles/robyn/issues/343) - Not able to see the added logs [\#342](https://github.com/sparckles/robyn/issues/342) - \[Feature Request\] Hope robyn can support returning f-string format [\#338](https://github.com/sparckles/robyn/issues/338) - \[Feature Request\] Refactor Robyn response to allow objects other than strings [\#336](https://github.com/sparckles/robyn/issues/336) - \[BUG\] Custom headers not sent when const=False [\#323](https://github.com/sparckles/robyn/issues/323) - \[Feature Request\] Add documentation for custom template support in v0.19.0 [\#321](https://github.com/sparckles/robyn/issues/321) - \[BUG\] Always need to return a string in a route [\#305](https://github.com/sparckles/robyn/issues/305) **Merged pull requests:** - fix: fix the static file serving [\#347](https://github.com/sparckles/robyn/pull/347) ([sansyrox](https://github.com/sansyrox)) - feat: return Response from routes [\#346](https://github.com/sparckles/robyn/pull/346) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.20.0](https://github.com/sparckles/robyn/tree/v0.20.0) (2022-12-20) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.19.2...v0.20.0) **Closed issues:** - \[Feature Request\] Add an automated benchmark script [\#320](https://github.com/sparckles/robyn/issues/320) **Merged pull requests:** - feat: allow non string types in response [\#337](https://github.com/sparckles/robyn/pull/337) ([sansyrox](https://github.com/sansyrox)) - feat: add an auto benchmark script [\#329](https://github.com/sparckles/robyn/pull/329) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.19.2](https://github.com/sparckles/robyn/tree/v0.19.2) (2022-12-14) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.19.1...v0.19.2) **Closed issues:** - \[BUG\] The --dev flag not working on Ubuntu 20.04 [\#332](https://github.com/sparckles/robyn/issues/332) - \[Feature Request\] Allow the ability of sending the headers from the same route [\#325](https://github.com/sparckles/robyn/issues/325) **Merged pull requests:** - fix: allow response headers and fix headers not working in const requests [\#331](https://github.com/sparckles/robyn/pull/331) ([sansyrox](https://github.com/sansyrox)) - fix: factorizing code [\#322](https://github.com/sparckles/robyn/pull/322) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.19.1](https://github.com/sparckles/robyn/tree/v0.19.1) (2022-12-03) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.19.0...v0.19.1) ## [v0.19.0](https://github.com/sparckles/robyn/tree/v0.19.0) (2022-12-02) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.18.3...v0.19.0) **Closed issues:** - \[Feature Request\] Allow the ability of sending the headers from the same route [\#326](https://github.com/sparckles/robyn/issues/326) - \[Feature Request\] Allow the ability of sending the headers from the same route [\#324](https://github.com/sparckles/robyn/issues/324) - \[BUG\] Error in Examples section in Documentation [\#314](https://github.com/sparckles/robyn/issues/314) - \[BUG\] Wrong link for the blog post on Robyn [\#306](https://github.com/sparckles/robyn/issues/306) - Add documentation about deployment [\#93](https://github.com/sparckles/robyn/issues/93) - Add support for templates! [\#10](https://github.com/sparckles/robyn/issues/10) **Merged pull requests:** - docs: update hosting docs [\#319](https://github.com/sparckles/robyn/pull/319) ([sansyrox](https://github.com/sansyrox)) - Various improvements around the index method [\#318](https://github.com/sparckles/robyn/pull/318) ([AntoineRR](https://github.com/AntoineRR)) - Add Railway deployment process. [\#316](https://github.com/sparckles/robyn/pull/316) ([carlosm27](https://github.com/carlosm27)) - docs: fix middleware section in examples [\#315](https://github.com/sparckles/robyn/pull/315) ([sansyrox](https://github.com/sansyrox)) - docs: fix blog link in website [\#309](https://github.com/sparckles/robyn/pull/309) ([sansyrox](https://github.com/sansyrox)) - Router refactor [\#307](https://github.com/sparckles/robyn/pull/307) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.18.3](https://github.com/sparckles/robyn/tree/v0.18.3) (2022-11-10) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.18.2...v0.18.3) **Closed issues:** - \[BUG\] `--log-level` not working [\#300](https://github.com/sparckles/robyn/issues/300) - \[Feature Request\] Refactor Code to include better types [\#254](https://github.com/sparckles/robyn/issues/254) **Merged pull requests:** - fix: log level not working [\#303](https://github.com/sparckles/robyn/pull/303) ([sansyrox](https://github.com/sansyrox)) - add route type enum [\#299](https://github.com/sparckles/robyn/pull/299) ([suhailmalik07](https://github.com/suhailmalik07)) ## [v0.18.2](https://github.com/sparckles/robyn/tree/v0.18.2) (2022-11-05) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.18.1...v0.18.2) **Closed issues:** - \[Feature Request?\] Update `matchit` crate to the most recent version [\#291](https://github.com/sparckles/robyn/issues/291) - \[Feature Request\] Add `@wraps` in route dectorators [\#285](https://github.com/sparckles/robyn/issues/285) - \[Feature Request\] fix clippy issues [\#265](https://github.com/sparckles/robyn/issues/265) **Merged pull requests:** - style: add logging for url port and host [\#304](https://github.com/sparckles/robyn/pull/304) ([sansyrox](https://github.com/sansyrox)) - fix config of port and url [\#302](https://github.com/sparckles/robyn/pull/302) ([kimhyun5u](https://github.com/kimhyun5u)) - update rust packages to latest [\#298](https://github.com/sparckles/robyn/pull/298) ([suhailmalik07](https://github.com/suhailmalik07)) - fix: retain metadata of the route functions [\#295](https://github.com/sparckles/robyn/pull/295) ([sansyrox](https://github.com/sansyrox)) - `SocketHeld::new` refactor [\#294](https://github.com/sparckles/robyn/pull/294) ([Jamyw7g](https://github.com/Jamyw7g)) ## [v0.18.1](https://github.com/sparckles/robyn/tree/v0.18.1) (2022-10-23) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.18.0...v0.18.1) **Merged pull requests:** - fix: replaced match with if let [\#293](https://github.com/sparckles/robyn/pull/293) ([Markaeus](https://github.com/Markaeus)) - Hotfix detecting robyn.env [\#292](https://github.com/sparckles/robyn/pull/292) ([Shending-Help](https://github.com/Shending-Help)) - fix: enable hot reload on windows [\#290](https://github.com/sparckles/robyn/pull/290) ([guilefoylegaurav](https://github.com/guilefoylegaurav)) ## [v0.18.0](https://github.com/sparckles/robyn/tree/v0.18.0) (2022-10-12) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.17.5...v0.18.0) **Closed issues:** - \[BUG\] The --dev mode spawns more servers without clearing previous ones. [\#249](https://github.com/sparckles/robyn/issues/249) - \[Feature\] Add support for Env variables and a robyn.yaml config file [\#97](https://github.com/sparckles/robyn/issues/97) **Merged pull requests:** - testing env support [\#288](https://github.com/sparckles/robyn/pull/288) ([Shending-Help](https://github.com/Shending-Help)) - Feature add support for env variables [\#286](https://github.com/sparckles/robyn/pull/286) ([Shending-Help](https://github.com/Shending-Help)) - fix: add proper kill process to conftest. \#249 [\#278](https://github.com/sparckles/robyn/pull/278) ([guilefoylegaurav](https://github.com/guilefoylegaurav)) ## [v0.17.5](https://github.com/sparckles/robyn/tree/v0.17.5) (2022-09-14) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.17.4...v0.17.5) **Closed issues:** - \[BUG\] README.md Discord link is invalid [\#272](https://github.com/sparckles/robyn/issues/272) - \[Feature Request\] Add Digital Ocean to list of sponsors in Robyn Docs [\#270](https://github.com/sparckles/robyn/issues/270) - \[Feature Request\] Add PyCon USA lightning talk in resources section [\#204](https://github.com/sparckles/robyn/issues/204) - \[Feature Request\] Add community/ resources section in Docs or README [\#203](https://github.com/sparckles/robyn/issues/203) - \[Feature Request\] Update the new architecture on the docs website [\#191](https://github.com/sparckles/robyn/issues/191) - Add examples section [\#101](https://github.com/sparckles/robyn/issues/101) **Merged pull requests:** - Don't run sync functions in pool [\#282](https://github.com/sparckles/robyn/pull/282) ([JackThomson2](https://github.com/JackThomson2)) - Add documentation of Adding GraphQL support | version 1 [\#275](https://github.com/sparckles/robyn/pull/275) ([sansyrox](https://github.com/sansyrox)) - docs: improve documentation [\#269](https://github.com/sparckles/robyn/pull/269) ([sansyrox](https://github.com/sansyrox)) ## [v0.17.4](https://github.com/sparckles/robyn/tree/v0.17.4) (2022-08-25) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.17.3...v0.17.4) **Closed issues:** - \[BUG?\] Startup failure OSError: \[WinError 87\] The parameter is incorrect [\#252](https://github.com/sparckles/robyn/issues/252) - \[Feature Request\] Add mypy for pyi\(stubs\) synchronisation [\#226](https://github.com/sparckles/robyn/issues/226) - not working on mac/windows [\#140](https://github.com/sparckles/robyn/issues/140) **Merged pull requests:** - Father, forgive me, for I am adding inline types. [\#266](https://github.com/sparckles/robyn/pull/266) ([sansyrox](https://github.com/sansyrox)) ## [v0.17.3](https://github.com/sparckles/robyn/tree/v0.17.3) (2022-08-17) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.17.2...v0.17.3) **Merged pull requests:** - fix: parse int status code to str [\#264](https://github.com/sparckles/robyn/pull/264) ([hougesen](https://github.com/hougesen)) ## [v0.17.2](https://github.com/sparckles/robyn/tree/v0.17.2) (2022-08-11) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.17.1...v0.17.2) **Fixed bugs:** - Cannot run Robyn on Windows [\#139](https://github.com/sparckles/robyn/issues/139) **Closed issues:** - \[BUG\] Move away from circle ci [\#240](https://github.com/sparckles/robyn/issues/240) - Migrate the community to discord [\#239](https://github.com/sparckles/robyn/issues/239) - \[Feature Request\] Release on test pypi before releasing on the main PyPi [\#224](https://github.com/sparckles/robyn/issues/224) - For 0.8.x [\#75](https://github.com/sparckles/robyn/issues/75) - Add a layer of caching in front of router [\#59](https://github.com/sparckles/robyn/issues/59) **Merged pull requests:** - Windows fix [\#261](https://github.com/sparckles/robyn/pull/261) ([sansyrox](https://github.com/sansyrox)) - ci: enable fail fast for faster response time in the pipelines [\#260](https://github.com/sparckles/robyn/pull/260) ([sansyrox](https://github.com/sansyrox)) - ci: add github actions to publish every PR on test pypi [\#259](https://github.com/sparckles/robyn/pull/259) ([sansyrox](https://github.com/sansyrox)) - Fix typo in README [\#246](https://github.com/sparckles/robyn/pull/246) ([bartbroere](https://github.com/bartbroere)) - chore\(ci\): move pytest from CircleCi to Github Actions [\#241](https://github.com/sparckles/robyn/pull/241) ([AntoineRR](https://github.com/AntoineRR)) ## [v0.17.1](https://github.com/sparckles/robyn/tree/v0.17.1) (2022-07-19) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.17.0...v0.17.1) **Closed issues:** - \[Feature Request\] add clippy in ci [\#236](https://github.com/sparckles/robyn/issues/236) - \[BUG\] Headers not available [\#231](https://github.com/sparckles/robyn/issues/231) - \[Feature Request\] Add an all contributor bot in the README of the repo [\#225](https://github.com/sparckles/robyn/issues/225) **Merged pull requests:** - Add Rust CI [\#237](https://github.com/sparckles/robyn/pull/237) ([AntoineRR](https://github.com/AntoineRR)) - Contributors added in Readme [\#235](https://github.com/sparckles/robyn/pull/235) ([orvil1026](https://github.com/orvil1026)) - fix external project link in README [\#234](https://github.com/sparckles/robyn/pull/234) ([touilleMan](https://github.com/touilleMan)) - fix: fix request headers not being propagated [\#232](https://github.com/sparckles/robyn/pull/232) ([sansyrox](https://github.com/sansyrox)) - Upgrade GitHub Actions and add Python 3.10 [\#230](https://github.com/sparckles/robyn/pull/230) ([cclauss](https://github.com/cclauss)) - OrbUp: Upgrade the CircleCI Orbs [\#229](https://github.com/sparckles/robyn/pull/229) ([cclauss](https://github.com/cclauss)) - CHANGELOG.md: Fix typo [\#228](https://github.com/sparckles/robyn/pull/228) ([cclauss](https://github.com/cclauss)) ## [v0.17.0](https://github.com/sparckles/robyn/tree/v0.17.0) (2022-07-06) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.6...v0.17.0) **Closed issues:** - A refactor [\#176](https://github.com/sparckles/robyn/issues/176) - \[Proposal\] Const Requests [\#48](https://github.com/sparckles/robyn/issues/48) **Merged pull requests:** - Add a const router [\#210](https://github.com/sparckles/robyn/pull/210) ([sansyrox](https://github.com/sansyrox)) ## [v0.16.6](https://github.com/sparckles/robyn/tree/v0.16.6) (2022-07-02) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.5...v0.16.6) ## [v0.16.5](https://github.com/sparckles/robyn/tree/v0.16.5) (2022-07-01) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.4...v0.16.5) **Closed issues:** - \[Feature Request\] Add sponsors in the repo and website [\#212](https://github.com/sparckles/robyn/issues/212) - \[Feature Request\] Add commitizen as a dev dependency [\#211](https://github.com/sparckles/robyn/issues/211) - Add better logging [\#158](https://github.com/sparckles/robyn/issues/158) - Remove freeport dependency [\#151](https://github.com/sparckles/robyn/issues/151) - Add websocket support [\#104](https://github.com/sparckles/robyn/issues/104) - Maintenance issue [\#56](https://github.com/sparckles/robyn/issues/56) - Improve Readme [\#4](https://github.com/sparckles/robyn/issues/4) **Merged pull requests:** - fix: Fixes the crashing dev mode [\#218](https://github.com/sparckles/robyn/pull/218) ([sansyrox](https://github.com/sansyrox)) - feat: add commitizen as a dev dependency [\#216](https://github.com/sparckles/robyn/pull/216) ([sansyrox](https://github.com/sansyrox)) - Isort imports [\#205](https://github.com/sparckles/robyn/pull/205) ([sansyrox](https://github.com/sansyrox)) - Add bridged logger. Improves performance substantially. [\#201](https://github.com/sparckles/robyn/pull/201) ([sansyrox](https://github.com/sansyrox)) - Adds pre-commit hooks for black, flake8, isort [\#198](https://github.com/sparckles/robyn/pull/198) ([chrismoradi](https://github.com/chrismoradi)) - Resolves port open issue when app is killed \#183 [\#196](https://github.com/sparckles/robyn/pull/196) ([anandtripathi5](https://github.com/anandtripathi5)) - Removing unwraps [\#195](https://github.com/sparckles/robyn/pull/195) ([sansyrox](https://github.com/sansyrox)) ## [v0.16.4](https://github.com/sparckles/robyn/tree/v0.16.4) (2022-05-30) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.3...v0.16.4) **Closed issues:** - \[Feature Request\] Remove extra logs [\#200](https://github.com/sparckles/robyn/issues/200) - \[Feature Request\] Add precommit hook for black, flake8 and isort [\#194](https://github.com/sparckles/robyn/issues/194) - \[BUG\] Get rid of Hashmap Clones and Unwraps! [\#186](https://github.com/sparckles/robyn/issues/186) ## [v0.16.3](https://github.com/sparckles/robyn/tree/v0.16.3) (2022-05-18) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.2...v0.16.3) **Closed issues:** - \[BUG\] Port not being free on app kill [\#183](https://github.com/sparckles/robyn/issues/183) - Build failure [\#166](https://github.com/sparckles/robyn/issues/166) ## [v0.16.2](https://github.com/sparckles/robyn/tree/v0.16.2) (2022-05-09) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.1...v0.16.2) ## [v0.16.1](https://github.com/sparckles/robyn/tree/v0.16.1) (2022-05-09) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.16.0...v0.16.1) **Closed issues:** - Add Python stubs [\#130](https://github.com/sparckles/robyn/issues/130) **Merged pull requests:** - Setup types for Robyn [\#192](https://github.com/sparckles/robyn/pull/192) ([sansyrox](https://github.com/sansyrox)) - Fix build pipeline [\#190](https://github.com/sparckles/robyn/pull/190) ([sansyrox](https://github.com/sansyrox)) - fix typo :pencil2: in api docs. [\#189](https://github.com/sparckles/robyn/pull/189) ([sombralibre](https://github.com/sombralibre)) - Remove hashmap clones [\#187](https://github.com/sparckles/robyn/pull/187) ([sansyrox](https://github.com/sansyrox)) - Code clean up | Modularise rust code [\#185](https://github.com/sparckles/robyn/pull/185) ([sansyrox](https://github.com/sansyrox)) - Add experimental io-uring [\#184](https://github.com/sparckles/robyn/pull/184) ([sansyrox](https://github.com/sansyrox)) - Implement Response headers [\#179](https://github.com/sparckles/robyn/pull/179) ([sansyrox](https://github.com/sansyrox)) - Code cleanup [\#178](https://github.com/sparckles/robyn/pull/178) ([sansyrox](https://github.com/sansyrox)) ## [v0.16.0](https://github.com/sparckles/robyn/tree/v0.16.0) (2022-04-29) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.15.1...v0.16.0) **Closed issues:** - \[Feature Request\] Add list of sponsors on the project website [\#182](https://github.com/sparckles/robyn/issues/182) - Optional build feature for io\_uring [\#177](https://github.com/sparckles/robyn/issues/177) - Create Custom headers for the response. [\#174](https://github.com/sparckles/robyn/issues/174) ## [v0.15.1](https://github.com/sparckles/robyn/tree/v0.15.1) (2022-03-24) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.15.0...v0.15.1) **Closed issues:** - Add middleware support [\#95](https://github.com/sparckles/robyn/issues/95) **Merged pull requests:** - Make websocket id accessible [\#173](https://github.com/sparckles/robyn/pull/173) ([sansyrox](https://github.com/sansyrox)) - Use Clippy tool optimized code [\#171](https://github.com/sparckles/robyn/pull/171) ([mrxiaozhuox](https://github.com/mrxiaozhuox)) - Modify headers [\#170](https://github.com/sparckles/robyn/pull/170) ([sansyrox](https://github.com/sansyrox)) - Update README.md [\#168](https://github.com/sparckles/robyn/pull/168) ([Polokghosh53](https://github.com/Polokghosh53)) ## [v0.15.0](https://github.com/sparckles/robyn/tree/v0.15.0) (2022-03-17) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.14.0...v0.15.0) **Closed issues:** - \[BUG\] Unable to modify headers in middlewares [\#167](https://github.com/sparckles/robyn/issues/167) - Add Pycon talk link to docs [\#102](https://github.com/sparckles/robyn/issues/102) ## [v0.14.0](https://github.com/sparckles/robyn/tree/v0.14.0) (2022-03-03) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.13.1...v0.14.0) **Fixed bugs:** - Build error [\#161](https://github.com/sparckles/robyn/issues/161) **Merged pull requests:** - Implement Custom Response objects. [\#165](https://github.com/sparckles/robyn/pull/165) ([sansyrox](https://github.com/sansyrox)) - Remove deprecated endpoints [\#162](https://github.com/sparckles/robyn/pull/162) ([sansyrox](https://github.com/sansyrox)) - Fix: default url param in app.start [\#160](https://github.com/sparckles/robyn/pull/160) ([sansyrox](https://github.com/sansyrox)) - Add middlewares [\#157](https://github.com/sparckles/robyn/pull/157) ([sansyrox](https://github.com/sansyrox)) - Remove arc\(ing\) [\#156](https://github.com/sparckles/robyn/pull/156) ([sansyrox](https://github.com/sansyrox)) ## [v0.13.1](https://github.com/sparckles/robyn/tree/v0.13.1) (2022-02-19) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.13.0...v0.13.1) ## [v0.13.0](https://github.com/sparckles/robyn/tree/v0.13.0) (2022-02-15) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.12.1...v0.13.0) ## [v0.12.1](https://github.com/sparckles/robyn/tree/v0.12.1) (2022-02-13) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.12.0...v0.12.1) **Closed issues:** - \[BUG\] Default URL cannot be assigned [\#159](https://github.com/sparckles/robyn/issues/159) - Upcoming release\(s\) [\#141](https://github.com/sparckles/robyn/issues/141) ## [v0.12.0](https://github.com/sparckles/robyn/tree/v0.12.0) (2022-01-21) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.11.1...v0.12.0) **Closed issues:** - Consider adding startup events [\#153](https://github.com/sparckles/robyn/issues/153) - Remove poetry dependency [\#150](https://github.com/sparckles/robyn/issues/150) **Merged pull requests:** - Add Event handlers [\#154](https://github.com/sparckles/robyn/pull/154) ([sansyrox](https://github.com/sansyrox)) - Remove poetry [\#152](https://github.com/sparckles/robyn/pull/152) ([sansyrox](https://github.com/sansyrox)) - Use print instead of input after starting server [\#149](https://github.com/sparckles/robyn/pull/149) ([klaa97](https://github.com/klaa97)) - Fix dev server [\#148](https://github.com/sparckles/robyn/pull/148) ([sansyrox](https://github.com/sansyrox)) - URL queries [\#146](https://github.com/sparckles/robyn/pull/146) ([patchgamestudio](https://github.com/patchgamestudio)) - Add project wide flake8 settings [\#143](https://github.com/sparckles/robyn/pull/143) ([sansyrox](https://github.com/sansyrox)) ## [v0.11.1](https://github.com/sparckles/robyn/tree/v0.11.1) (2022-01-11) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.11.0...v0.11.1) ## [v0.11.0](https://github.com/sparckles/robyn/tree/v0.11.0) (2022-01-07) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.10.0...v0.11.0) **Fixed bugs:** - Hot Reloading goes in an infinite loop [\#115](https://github.com/sparckles/robyn/issues/115) **Closed issues:** - Benchmarks to Björn, uvicorn etc. [\#142](https://github.com/sparckles/robyn/issues/142) - Add Python linter setup [\#129](https://github.com/sparckles/robyn/issues/129) - Add fixtures in testing [\#84](https://github.com/sparckles/robyn/issues/84) ## [v0.10.0](https://github.com/sparckles/robyn/tree/v0.10.0) (2021-12-20) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.9.0...v0.10.0) **Closed issues:** - Add PyPI classifiers [\#127](https://github.com/sparckles/robyn/issues/127) - Robyn version 0.9.0 doesn't work on Mac M1 Models [\#120](https://github.com/sparckles/robyn/issues/120) - Inconsistency in steps mentioned in Readme to run locally [\#119](https://github.com/sparckles/robyn/issues/119) - Async web socket support [\#116](https://github.com/sparckles/robyn/issues/116) - Reveal Logo to be removed from Future Roadmap [\#107](https://github.com/sparckles/robyn/issues/107) - Dead Link for Test Drive Button on Robyn Landing Page [\#106](https://github.com/sparckles/robyn/issues/106) - Add issue template, pr template and community guidelines [\#105](https://github.com/sparckles/robyn/issues/105) - For v0.7.0 [\#72](https://github.com/sparckles/robyn/issues/72) - Add better support for requests and response! [\#13](https://github.com/sparckles/robyn/issues/13) **Merged pull requests:** - Add async support in WS [\#134](https://github.com/sparckles/robyn/pull/134) ([sansyrox](https://github.com/sansyrox)) - Add help messages and simplify 'dev' option [\#128](https://github.com/sparckles/robyn/pull/128) ([Kludex](https://github.com/Kludex)) - Apply Python highlight on api.md [\#126](https://github.com/sparckles/robyn/pull/126) ([Kludex](https://github.com/Kludex)) - Update comparison.md [\#124](https://github.com/sparckles/robyn/pull/124) ([Kludex](https://github.com/Kludex)) - Update comparison.md [\#123](https://github.com/sparckles/robyn/pull/123) ([Kludex](https://github.com/Kludex)) - Fix readme documentation [\#122](https://github.com/sparckles/robyn/pull/122) ([sansyrox](https://github.com/sansyrox)) - Release v0.9.0 Changelog [\#121](https://github.com/sparckles/robyn/pull/121) ([sansyrox](https://github.com/sansyrox)) - \[FEAT\] Open Source Contribution Templates [\#118](https://github.com/sparckles/robyn/pull/118) ([shivaylamba](https://github.com/shivaylamba)) - FIX : Wrong link for Test Drive [\#117](https://github.com/sparckles/robyn/pull/117) ([shivaylamba](https://github.com/shivaylamba)) ## [v0.9.0](https://github.com/sparckles/robyn/tree/v0.9.0) (2021-12-01) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.8.1...v0.9.0) **Closed issues:** - Add more HTTP methods [\#74](https://github.com/sparckles/robyn/issues/74) **Merged pull requests:** - Fix default url bug [\#111](https://github.com/sparckles/robyn/pull/111) ([sansyrox](https://github.com/sansyrox)) - Web socket integration attempt 2 [\#109](https://github.com/sparckles/robyn/pull/109) ([sansyrox](https://github.com/sansyrox)) ## [v0.8.1](https://github.com/sparckles/robyn/tree/v0.8.1) (2021-11-17) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.8.0...v0.8.1) **Fixed bugs:** - The default start is running the server at '0.0.0.0' instead of '127.0.0.1' [\#110](https://github.com/sparckles/robyn/issues/110) ## [v0.8.0](https://github.com/sparckles/robyn/tree/v0.8.0) (2021-11-10) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.7.1...v0.8.0) **Closed issues:** - Share the TCP web socket across different cores [\#91](https://github.com/sparckles/robyn/issues/91) - Improve the router [\#52](https://github.com/sparckles/robyn/issues/52) - \[Stretch Goal\] Create a a way of writing async request [\#32](https://github.com/sparckles/robyn/issues/32) - Improve the router [\#29](https://github.com/sparckles/robyn/issues/29) **Merged pull requests:** - Fix the failing testing suite! [\#100](https://github.com/sparckles/robyn/pull/100) ([sansyrox](https://github.com/sansyrox)) - Requests object is now optional [\#99](https://github.com/sparckles/robyn/pull/99) ([sansyrox](https://github.com/sansyrox)) - Add socket sharing [\#94](https://github.com/sparckles/robyn/pull/94) ([sansyrox](https://github.com/sansyrox)) ## [v0.7.1](https://github.com/sparckles/robyn/tree/v0.7.1) (2021-10-28) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.7.0...v0.7.1) **Closed issues:** - Remove the solution using dockerisation of tests [\#98](https://github.com/sparckles/robyn/issues/98) - Functions not working without request param [\#96](https://github.com/sparckles/robyn/issues/96) - Add actix router [\#85](https://github.com/sparckles/robyn/issues/85) - Request apart from GET are not working in directory subroutes [\#79](https://github.com/sparckles/robyn/issues/79) - Add the ability to share the server across the network [\#69](https://github.com/sparckles/robyn/issues/69) - Add the ability to view headers in the HTTP Methods [\#54](https://github.com/sparckles/robyn/issues/54) - Add tests! [\#8](https://github.com/sparckles/robyn/issues/8) ## [v0.7.0](https://github.com/sparckles/robyn/tree/v0.7.0) (2021-10-03) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.6.1...v0.7.0) **Closed issues:** - Robyn the replacement of Quart [\#86](https://github.com/sparckles/robyn/issues/86) - Add Pytest support for the test endpoints [\#81](https://github.com/sparckles/robyn/issues/81) **Merged pull requests:** - Finally completed router integration [\#90](https://github.com/sparckles/robyn/pull/90) ([sansyrox](https://github.com/sansyrox)) - Address clippy lints [\#89](https://github.com/sparckles/robyn/pull/89) ([SanchithHegde](https://github.com/SanchithHegde)) - Initial docs update [\#83](https://github.com/sparckles/robyn/pull/83) ([sansyrox](https://github.com/sansyrox)) - Add the basics of python testing [\#82](https://github.com/sparckles/robyn/pull/82) ([sansyrox](https://github.com/sansyrox)) - Add a new landing page [\#80](https://github.com/sparckles/robyn/pull/80) ([sansyrox](https://github.com/sansyrox)) ## [v0.6.1](https://github.com/sparckles/robyn/tree/v0.6.1) (2021-08-30) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.6.0...v0.6.1) **Closed issues:** - Make a new release [\#71](https://github.com/sparckles/robyn/issues/71) - Update to the pyo3 v0.14 [\#63](https://github.com/sparckles/robyn/issues/63) - Add the support to serve static directories [\#55](https://github.com/sparckles/robyn/issues/55) - Add support for mounting directory [\#38](https://github.com/sparckles/robyn/issues/38) **Merged pull requests:** - Add the base of http requests [\#78](https://github.com/sparckles/robyn/pull/78) ([sansyrox](https://github.com/sansyrox)) - Add default port and a variable url [\#77](https://github.com/sparckles/robyn/pull/77) ([sansyrox](https://github.com/sansyrox)) - Make the request object accessible in every route [\#76](https://github.com/sparckles/robyn/pull/76) ([sansyrox](https://github.com/sansyrox)) - Add the basics for circle ci and testing framework [\#67](https://github.com/sparckles/robyn/pull/67) ([sansyrox](https://github.com/sansyrox)) - Update to pyo3 v0.14 [\#65](https://github.com/sparckles/robyn/pull/65) ([sansyrox](https://github.com/sansyrox)) - Add the static directory serving [\#64](https://github.com/sparckles/robyn/pull/64) ([sansyrox](https://github.com/sansyrox)) - Create a request object [\#61](https://github.com/sparckles/robyn/pull/61) ([sansyrox](https://github.com/sansyrox)) - Add the ability to add body in PUT, PATCH and DELETE [\#60](https://github.com/sparckles/robyn/pull/60) ([sansyrox](https://github.com/sansyrox)) - Implement a working dev server [\#40](https://github.com/sparckles/robyn/pull/40) ([sansyrox](https://github.com/sansyrox)) - Use Actix as base [\#35](https://github.com/sparckles/robyn/pull/35) ([JackThomson2](https://github.com/JackThomson2)) ## [v0.6.0](https://github.com/sparckles/robyn/tree/v0.6.0) (2021-08-11) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.5.3...v0.6.0) **Closed issues:** - Add body support for PUT, POST and PATCH [\#53](https://github.com/sparckles/robyn/issues/53) - Away with limited internet access till 1st August [\#51](https://github.com/sparckles/robyn/issues/51) - Add doc stings [\#42](https://github.com/sparckles/robyn/issues/42) - OSX builds are failing [\#41](https://github.com/sparckles/robyn/issues/41) - Add a dev server implementation [\#37](https://github.com/sparckles/robyn/issues/37) - Mini Roadmap | A list of issues that would require fixing [\#19](https://github.com/sparckles/robyn/issues/19) - Add support for Object/JSON Return Type! [\#9](https://github.com/sparckles/robyn/issues/9) ## [v0.5.3](https://github.com/sparckles/robyn/tree/v0.5.3) (2021-07-12) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.5.2...v0.5.3) **Merged pull requests:** - Improve the HTML file serving [\#46](https://github.com/sparckles/robyn/pull/46) ([sansyrox](https://github.com/sansyrox)) - Add the basics to add serving of static files [\#36](https://github.com/sparckles/robyn/pull/36) ([sansyrox](https://github.com/sansyrox)) ## [v0.5.2](https://github.com/sparckles/robyn/tree/v0.5.2) (2021-07-11) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.5.1...v0.5.2) ## [v0.5.1](https://github.com/sparckles/robyn/tree/v0.5.1) (2021-07-10) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.5.0...v0.5.1) **Closed issues:** - Make html file serving more robust [\#45](https://github.com/sparckles/robyn/issues/45) - Try to serve individual static files using vanilla rust [\#43](https://github.com/sparckles/robyn/issues/43) - Error on import [\#16](https://github.com/sparckles/robyn/issues/16) - Add multiple process sharing [\#2](https://github.com/sparckles/robyn/issues/2) ## [v0.5.0](https://github.com/sparckles/robyn/tree/v0.5.0) (2021-07-01) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.4.1...v0.5.0) **Closed issues:** - QPS drops drastically after processing many requests [\#31](https://github.com/sparckles/robyn/issues/31) - Improve the way you parse TCP streams [\#30](https://github.com/sparckles/robyn/issues/30) - Re-introduce thread pool for the sync functions \(maybe\) [\#22](https://github.com/sparckles/robyn/issues/22) - Add async listener object in rust stream! [\#11](https://github.com/sparckles/robyn/issues/11) **Merged pull requests:** - Make the server http compliant [\#33](https://github.com/sparckles/robyn/pull/33) ([sansyrox](https://github.com/sansyrox)) ## [v0.4.1](https://github.com/sparckles/robyn/tree/v0.4.1) (2021-06-26) [Full Changelog](https://github.com/sparckles/robyn/compare/0.4.0...v0.4.1) **Closed issues:** - Add PyPi Metadata [\#5](https://github.com/sparckles/robyn/issues/5) **Merged pull requests:** - Build and publish wheels on GitHub Actions [\#26](https://github.com/sparckles/robyn/pull/26) ([messense](https://github.com/messense)) - Code cleanup using PyFunction type [\#25](https://github.com/sparckles/robyn/pull/25) ([sansyrox](https://github.com/sansyrox)) - Add non blocking sync functions [\#23](https://github.com/sparckles/robyn/pull/23) ([sansyrox](https://github.com/sansyrox)) - Add support for sync functions [\#20](https://github.com/sparckles/robyn/pull/20) ([sansyrox](https://github.com/sansyrox)) ## [0.4.0](https://github.com/sparckles/robyn/tree/0.4.0) (2021-06-22) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.3.0...0.4.0) **Closed issues:** - Add support for Sync functions as well! [\#7](https://github.com/sparckles/robyn/issues/7) ## [v0.3.0](https://github.com/sparckles/robyn/tree/v0.3.0) (2021-06-21) [Full Changelog](https://github.com/sparckles/robyn/compare/v0.2.3...v0.3.0) **Closed issues:** - Architecture link in readme redirects to raw content [\#18](https://github.com/sparckles/robyn/issues/18) - Link pointing to the wrong destination [\#6](https://github.com/sparckles/robyn/issues/6) **Merged pull requests:** - Pure tokio [\#17](https://github.com/sparckles/robyn/pull/17) ([JackThomson2](https://github.com/JackThomson2)) - Remove Mutex lock on Threadpool and routes [\#15](https://github.com/sparckles/robyn/pull/15) ([JackThomson2](https://github.com/JackThomson2)) ## [v0.2.3](https://github.com/sparckles/robyn/tree/v0.2.3) (2021-06-18) [Full Changelog](https://github.com/sparckles/robyn/compare/c14f52e6faa79917e89de4220590da7bf28f6a65...v0.2.3) **Closed issues:** - Improve async runtime [\#3](https://github.com/sparckles/robyn/issues/3) \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* ================================================ FILE: CODE_OF_CONDUCT.md ================================================ ### Robyn Open Source Community Guidelines - **Be friendly and patient**. - **Be welcoming**. - **Be respectful**. - **Be careful in the words that we choose**. ================================================ FILE: CONTRIBUTING.md ================================================ ## Contributing Guidelines First off, thank you for considering contributing to `Robyn`. This guide details all the general information that one should know before contributing to the project. Please stick as close as possible to the guidelines. That way, we ensure that you have a smooth experience contributing to this project. ### General Rules: These are, in general, rules that you should be following while contributing to an Open-Source project : - Be Nice, Be Respectful (BNBR) - Check if the Issue you created, exists or not. - While creating a new issue, make sure you describe the issue clearly. - Make proper commit messages and document your PR well. - Always add comments in your Code and explain it at points if possible, add Doctest. - Always create a Pull Request from a Branch; Never from the Main. - Follow proper code conventions because writing clean code is important. - Issues would be assigned on a "First Come, First Served" basis. - Do mention (@sansyrox) the project maintainer if your PR isn't reviewed within a few days. ## First time contributors: Pushing files in your own repository is easy, but how to contribute to someone else's project? If you have the same question, then below are the steps that you can follow to make your first contribution in this repository. ### Pull Request **1.** The very first step includes forking the project. Click on the `fork` button as shown below to fork the project.


**2.** Clone the forked repository. Open up the GitBash/Command Line and type ``` git clone https://github.com//robyn.git ``` **3.** Navigate to the project directory. ``` cd robyn ``` **4.** Add a reference to the original repository. ``` git remote add upstream https://github.com/sparckles/robyn.git ``` **5.** See latest changes to the repo using ``` git remote -v ``` **6.** Create a new branch. ``` git checkout -b ``` **7.** Always take a pull from the upstream repository to your main branch to keep it even with the main project. This will save you from frequent merge conflicts. ``` git pull upstream main ``` **8.** You can make the required changes now. Make appropriate commits with proper commit messages. **9.** Add and then commit your changes. ``` git add . ``` ``` git commit -m "" ``` **10.** Push your local branch to the remote repository. ``` git push -u origin ``` **11.** Once you have pushed the changes to your repository, go to your forked repository. Click on the `Compare & pull request` button as shown below.


**12.** The image below is what the new page would look like. Give a proper title to your PR and describe the changes made by you in the description box.(Note - Sometimes there are PR templates which are to be filled as instructed.)


**13.** Open a pull request by clicking the `Create pull request` button. `Voila, you have made your first contribution to this project` ## Issue - Issues can be used to keep track of bugs, enhancements, or other requests. Creating an issue to let the project maintainers know about the changes you are planning to make before raising a PR is a good open-source practice.
Let's walk through the steps to create an issue: **1.** On GitHub, navigate to the main page of the repository. [Here](https://github.com/sparckles/robyn.git) in this case. **2.** Under your repository name, click on the `Issues` button.


**3.** Click on the `New issue` button.


**4.** Select one of the Issue Templates to get started.


**5.** Fill in the appropriate `Title` and `Issue description` and click on `Submit new issue`.


### Tutorials that may help you: - [Git & GitHub Tutorial](https://www.youtube.com/watch?v=RGOj5yH7evk) - [Resolve merge conflict](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github) ================================================ FILE: Cargo.toml ================================================ [package] name = "robyn" version = "0.82.0" authors = ["Sanskar Jethi "] edition = "2021" description = "Robyn is a Super Fast Async Python Web Framework with a Rust runtime." license = "BSD License (BSD)" homepage = "https://github.com/sparckles/robyn" readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] name = "robyn" crate-type = ["cdylib", "rlib"] [dependencies] pyo3 = { version = "0.27.2", features = ["extension-module", "py-clone"]} pyo3-async-runtimes = { version = "0.27", features = ["tokio-runtime"] } pyo3-async-runtimes-macros = { version = "0.27" } pyo3-log = "0.13.2" tokio = { version = "1.40", features = ["full"] } dashmap = "5.4.3" anyhow = "1.0.69" actix = "0.13.4" actix-web-actors = "4.3.0" actix-web = "4.4.2" actix-http = "3.3.1" actix-files = "0.6.2" futures = "0.3.27" futures-util = "0.3.27" matchit = "0.7.3" socket2 = { version = "0.5.1", features = ["all"] } uuid = { version = "1.3.0", features = ["serde", "v4"] } log = "0.4.17" pythonize = "0.27" serde = "1.0.187" serde_json = "1.0.109" once_cell = "1.8.0" actix-multipart = "0.6.1" parking_lot = "0.12.3" crossbeam-channel = "0.5" [features] io-uring = ["actix-web/experimental-io-uring"] [profile.release] codegen-units = 1 lto = "fat" panic = "abort" strip = true opt-level = 3 [profile.release.build-override] opt-level = 3 [package.metadata.maturin] name = "robyn" ================================================ FILE: LICENSE ================================================ BSD 2-Clause License Copyright (c) 2021, Sanskar Jethi All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================

Robyn Logo

# Robyn [![Twitter](https://badgen.net/badge/icon/twitter?icon=twitter&label)](https://twitter.com/Robyn_oss) [![Downloads](https://static.pepy.tech/personalized-badge/Robyn?period=total&units=international_system&left_color=grey&right_color=blue&left_text=Downloads)](https://pepy.tech/project/Robyn) [![GitHub tag](https://img.shields.io/github/tag/sparckles/Robyn?include_prereleases=&sort=semver&color=black)](https://github.com/sparckles/Robyn/releases/) [![License](https://img.shields.io/badge/License-BSD_2.0-black)](https://github.com/sparckles/Robyn/blob/main/LICENSE) ![Python](https://img.shields.io/badge/Support-Version%20%E2%89%A5%203.10-brightgreen) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/sparckles/Robyn) [![view - Documentation](https://img.shields.io/badge/view-Documentation-blue?style=for-the-badge)](https://robyn.tech/documentation) [![Discord](https://img.shields.io/discord/999782964143603713?label=discord&logo=discord&logoColor=white&style=for-the-badge&color=blue)](https://discord.gg/rkERZ5eNU8) [![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20Robyn%20Guru-006BFF?style=for-the-badge)](https://gurubase.io/g/robyn) Robyn is a High-Performance, Community-Driven, and Innovator Friendly Web Framework with a Rust runtime. You can learn more by checking our [community resources](https://robyn.tech/documentation/en/community-resources#talks)! image Source: [TechEmpower Round 22](https://www.techempower.com/benchmarks/#section=data-r22&test=plaintext) ## 📦 Installation You can simply use Pip for installation. ```bash pip install robyn ``` Or, with [conda-forge](https://conda-forge.org/) ```bash conda install -c conda-forge robyn ``` To install with all optional features (Pydantic validation, Jinja2 templating): ```bash pip install "robyn[all]" ``` ## 🤔 Usage ### 🚀 Define your API To define your API, you can add the following code in an `app.py` file. ```python from robyn import Robyn app = Robyn(__file__) @app.get("/") async def h(request): return "Hello, world!" app.start(port=8080) ``` ### 🏃 Run your code Simply run the app.py file you created. You will then have access to a server on the `localhost:8080`, that you can request from an other program. Robyn provides several options to customize your web server. ``` $ python3 app.py ``` To see the usage ``` usage: app.py [-h] [--processes PROCESSES] [--workers WORKERS] [--dev] [--log-level LOG_LEVEL] Robyn, a fast async web framework with a rust runtime. options: -h, --help show this help message and exit --processes PROCESSES Choose the number of processes. [Default: 1] --workers WORKERS Choose the number of workers. [Default: 1] --dev Development mode. It restarts the server based on file changes. --log-level LOG_LEVEL Set the log level name --create Create a new project template. --docs Open the Robyn documentation. --open-browser Open the browser on successful start. --version Show the Robyn version. --compile-rust-path COMPILE_RUST_PATH Compile rust files in the given path. --create-rust-file CREATE_RUST_FILE Create a rust file with the given name. --disable-openapi Disable the OpenAPI documentation. --fast Enable the fast mode. ``` Log level can be `DEBUG`, `INFO`, `WARNING`, or `ERROR`. When running the app using `--open-browser` a new browser window will open at the app location, e.g: ``` $ python3 app.py --open-browser ``` ### 💻 Add more routes You can add more routes to your API. Check out the routes in [this file](https://github.com/sparckles/Robyn/blob/main/integration_tests/base_routes.py) as examples. ### 🐍 Python Version Support Robyn is compatible with the following Python versions: > Python >= 3.10 It is recommended to use the latest version of Python for the best performances. Please make sure you have the correct version of Python installed before starting to use this project. You can check your Python version by running the following command in your terminal: ```bash python --version ``` ## 💡 Features - Under active development! - A multithreaded Runtime - Extensible - A simple API - Sync and Async Function Support - Dynamic URL Routing - Multi Core Scaling - WebSockets - Middlewares (before and after request hooks) - Built in form data handling - Dependency Injection - Hot Reloading - Direct Rust Integration - Automatic OpenAPI generation - Jinja2 Templating - Static File Serving - File Responses and Downloads - Authentication Support - CORS Configuration - Streaming / SSE Responses - Startup and Shutdown Events - Exception Handling - SubRouters - Project Scaffolding via CLI - Experimental io-uring Support - **🤖 AI Agent Support** - Built-in agent routing and execution - **🔌 MCP (Model Context Protocol)** - Connect to AI applications as a server - Community First and truly FOSS! ## 🗒️ How to contribute ### 🏁 Get started Please read the [code of conduct](https://github.com/sparckles/Robyn/blob/main/CODE_OF_CONDUCT.md) and go through [CONTRIBUTING.md](https://github.com/sparckles/Robyn/blob/main/CONTRIBUTING.md) before contributing to Robyn. Feel free to open an issue for any clarifications or suggestions. If you're feeling curious. You can take a look at a more detailed architecture [here](https://robyn.tech/documentation/architecture). If you still need help to get started, feel free to reach out on our [community discord](https://discord.gg/rkERZ5eNU8). ### ⚙️ To Develop Locally #### Prerequisites Before starting, ensure you have the following installed: - Python >= 3.10, <= 3.14 - Rust (latest stable) - C compiler (gcc/clang) #### Setup - Clone the repository: ``` git clone https://github.com/sparckles/Robyn.git ``` - Setup a virtual environment: ``` python3 -m venv .venv source .venv/bin/activate ``` - Install required packages ``` pip install pre-commit poetry maturin ``` - Install development dependencies ``` poetry install --with dev --with test ``` - Install pre-commit git hooks ``` pre-commit install ``` - Build & install Robyn Rust package ``` maturin develop ``` - Build & install Robyn Rust package (**experimental**) ``` maturin develop --cargo-extra-args="--features=io-uring" ``` - Run! ``` poetry run test_server ``` - Run all tests ``` pytest ``` - Run only the integration tests ``` pytest integration_tests ``` - Run only the unit tests (you don't need to be running the test_server for these) ``` pytest unit_tests ``` - Test (refer to `integration_tests/base_routes.py` for more endpoints) ``` curl http://localhost:8080/sync/str ``` - **tip:** One liners for testing changes! ``` maturin develop && poetry run test_server maturin develop && pytest ``` - **tip:** For IO-uring support, you can use the following command: ``` maturin develop --cargo-extra-args="--features=io-uring" ``` - **tip:** To use your local Robyn version in other projects, you can install it using pip: ``` pip install -e path/to/robyn/target/wheels/robyn---.whl ``` e.g. ``` pip install -e /repos/Robyn/target/wheels/robyn-0.63.0-cp312-cp312-macosx_10_15_universal2.whl ``` #### Troubleshooting If you face any issues, here are some common fixes: - install `patchelf` with `pip install patchelf` if you face `patchelf` not found issue during `maturin develop` (esp. on Arch Linux) - If you get Rust compilation errors, ensure you have a C compiler installed: - Ubuntu/Debian: `sudo apt install build-essential` - Fedora: `sudo dnf install gcc` - macOS: Install Xcode Command Line Tools - Windows: Install Visual Studio Build Tools ## ✨ Special thanks ### ✨ Contributors/Supporters Thanks to all the contributors of the project. Robyn will not be what it is without all your support :heart:. Special thanks to the [PyO3](https://pyo3.rs/v0.13.2/) community and [Andrew from PyO3-asyncio](https://github.com/awestlake87/pyo3-asyncio) for their amazing libraries and their support for my queries. 💖 ### ✨ Sponsors These sponsors help us make the magic happen! [![DigitalOcean Referral Badge](https://web-platforms.sfo2.cdn.digitaloceanspaces.com/WWW/Badge%201.svg)](https://www.digitalocean.com/?refcode=3f2b9fd4968d&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge) [![Appwrite Logo](https://avatars.githubusercontent.com/u/25003669?s=105&v=1)](https://github.com/appwrite) ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=sparckles/Robyn&type=Date)](https://star-history.com/#sparckles/Robyn&Date) ================================================ FILE: benchmark.sh ================================================ #!/bin/sh # Benchmark script to get info about Robyn's performances # You can use this benchmark when developing on Robyn to test if your changes had a huge # impact on performances. You cannot compare benchmarks from different machine and even # several runs on the same machine can give very different results sometimes. # Be aware of this when using this script! Help() { echo "Benchmark script to get info about Robyn's performances." echo echo "USAGE:" echo " benchmark [-h|m|n|y]" echo echo "OPTIONS:" echo " -h Print this help." echo " -m Run 'maturin develop' to compile the Rust part of Robyn." echo " -n Set the number of requests that oha sends." echo " -y Skip prompt" exit 0 } yes_flag=false run_maturin=false number=100000 while getopts hymn: opt; do case $opt in h) Help ;; y) yes_flag=true ;; m) run_maturin=true ;; n) number=$OPTARG ;; ?) echo 'Error in command line parsing' >&2 Help exit 1 ;; esac done # Prompt user to check if he installed the requirements for running the benchmark if [ "$yes_flag" = false ]; then echo "Make sure you are running this in your venv and you installed 'oha' using 'cargo install oha'" echo "Do you want to proceed?" while true; do read -p "" yn case $yn in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done fi # Compile Rust if $run_maturin; then maturin develop fi # Run the server in the background python3 ./integration_tests/base_routes.py & sleep 1 # oha will display benchmark results oha -n "$number" http://localhost:8080/sync # Kill subprocesses after exiting the script (python + robyn server) # (see https://stackoverflow.com/questions/360201/how-do-i-kill-background-processes-jobs-when-my-shell-script-exits) trap "trap - TERM && kill 0" INT TERM EXIT ================================================ FILE: ci-local.sh ================================================ #!/usr/bin/env bash set -euo pipefail RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' FAILED=() PASSED=() SKIPPED=() run_step() { local name="$1" shift echo -e "\n${CYAN}── $name ──${NC}" echo -e "${YELLOW}$ $*${NC}" if "$@"; then PASSED+=("$name") echo -e "${GREEN}✓ $name${NC}" else FAILED+=("$name") echo -e "${RED}✗ $name${NC}" fi } skip_step() { local name="$1" local reason="$2" SKIPPED+=("$name ($reason)") echo -e "\n${YELLOW}── $name [SKIPPED: $reason] ──${NC}" } usage() { echo "Usage: $0 [rust|lint|python|all|fix]" echo "" echo "Mirrors the GitHub Actions CI workflows locally." echo "" echo " rust Rust CI: cargo check, test, fmt --check, clippy" echo " lint Lint PR: ruff check, isort --check-only" echo " python Python CI: nox test suite (current Python version)" echo " all Everything (default)" echo " fix Auto-fix: cargo fmt, ruff --fix, isort" exit 0 } # ── rust-CI.yml ─────────────────────────────────────────────────────────────── run_rust() { echo -e "\n${CYAN}═══ Rust CI (.github/workflows/rust-CI.yml) ═══${NC}" run_step "cargo check" cargo check run_step "cargo test" cargo test run_step "cargo fmt" cargo fmt --check run_step "cargo clippy" cargo clippy } # ── lint-pr.yml ─────────────────────────────────────────────────────────────── run_lint() { echo -e "\n${CYAN}═══ Lint PR (.github/workflows/lint-pr.yml) ═══${NC}" if command -v ruff &>/dev/null; then run_step "ruff check" ruff check . else skip_step "ruff check" "ruff not installed (pip install ruff)" fi if command -v isort &>/dev/null; then run_step "isort check" isort --check-only --diff . else skip_step "isort check" "isort not installed (pip install isort)" fi } # ── python-CI.yml ───────────────────────────────────────────────────────────── run_python() { echo -e "\n${CYAN}═══ Python CI (.github/workflows/python-CI.yml) ═══${NC}" local pyver pyver=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") if command -v nox &>/dev/null; then run_step "nox (python $pyver)" nox --non-interactive --error-on-missing-interpreter -p "$pyver" else skip_step "nox tests" "nox not installed (pip install nox)" fi } # ── fix mode ────────────────────────────────────────────────────────────────── run_fix() { echo -e "\n${CYAN}═══ Auto-fix ═══${NC}" run_step "cargo fmt" cargo fmt command -v ruff &>/dev/null && run_step "ruff fix" ruff check --fix . || skip_step "ruff fix" "not installed" command -v isort &>/dev/null && run_step "isort fix" isort . || skip_step "isort fix" "not installed" } # ── main ────────────────────────────────────────────────────────────────────── MODE="${1:-all}" case "$MODE" in rust) run_rust ;; lint) run_lint ;; python) run_python ;; fix) run_fix ;; all) run_rust; run_lint; run_python ;; -h|--help|help) usage ;; *) echo "Unknown mode: $MODE"; usage ;; esac # ── summary ─────────────────────────────────────────────────────────────────── echo -e "\n${CYAN}═══ Summary ═══${NC}" for s in "${PASSED[@]+"${PASSED[@]}"}"; do echo -e " ${GREEN}✓${NC} $s"; done for s in "${SKIPPED[@]+"${SKIPPED[@]}"}"; do echo -e " ${YELLOW}⊘${NC} $s"; done for s in "${FAILED[@]+"${FAILED[@]}"}"; do echo -e " ${RED}✗${NC} $s"; done if [ ${#FAILED[@]} -gt 0 ]; then echo -e "\n${RED}CI would fail: ${#FAILED[@]} check(s) failed.${NC}" exit 1 else echo -e "\n${GREEN}All checks passed. Safe to push.${NC}" exit 0 fi ================================================ FILE: docs_src/.eslintrc.json ================================================ { "extends": ["next","next/core-web-vitals"], "rules": { "react/no-unescaped-entities": "off" } } ================================================ FILE: docs_src/.gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # testing /coverage # next.js /.next/ /out/ # production /build # misc .DS_Store *.pem # debug npm-debug.log* yarn-debug.log* yarn-error.log* .pnpm-debug.log* # local env files .env*.local # vercel .vercel # generated files /public/rss/ ================================================ FILE: docs_src/README.md ================================================ ## Docs Base This is the documentation website that will be used as a base for Robyn and Starfyre docs. ## Setup 1. Clone this repo 2. Run `npm install` 3. Run `npm run dev` 4. Open `http://localhost:3000` in your browser ================================================ FILE: docs_src/jsconfig.json ================================================ { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"] } } } ================================================ FILE: docs_src/mdx/recma.mjs ================================================ import { mdxAnnotations } from 'mdx-annotations' import recmaNextjsStaticProps from 'recma-nextjs-static-props' import { recmaImportImages } from 'recma-import-images' function recmaRemoveNamedExports() { return (tree) => { tree.body = tree.body.map((node) => { if (node.type === 'ExportNamedDeclaration') { return node.declaration } return node }) } } export const recmaPlugins = [ mdxAnnotations.recma, recmaRemoveNamedExports, recmaNextjsStaticProps, recmaImportImages, ] ================================================ FILE: docs_src/mdx/rehype.mjs ================================================ import { mdxAnnotations } from 'mdx-annotations' import { visit } from 'unist-util-visit' import rehypeMdxTitle from 'rehype-mdx-title' import shiki from 'shiki' import { toString } from 'mdast-util-to-string' import * as acorn from 'acorn' import { slugifyWithCounter } from '@sindresorhus/slugify' import rehypeSlug from 'rehype-slug' import { remarkRehypeWrap } from 'remark-rehype-wrap' import rehypeAutolinkHeadings from 'rehype-autolink-headings' function rehypeParseCodeBlocks() { return (tree) => { visit(tree, 'element', (node, _nodeIndex, parentNode) => { if (node.tagName === 'code' && node.properties.className) { parentNode.properties.language = node.properties.className[0]?.replace( /^language-/, '' ) } }) } } let highlighter function rehypeShiki() { return async (tree) => { highlighter = highlighter ?? (await shiki.getHighlighter({ theme: 'css-variables' })) visit(tree, 'element', (node) => { if (node.tagName === 'pre' && node.children[0]?.tagName === 'code') { let codeNode = node.children[0] let textNode = codeNode.children[0] node.properties.code = textNode.value if (node.properties.language) { let tokens = highlighter.codeToThemedTokens( textNode.value, node.properties.language ) textNode.value = shiki.renderToHtml(tokens, { elements: { pre: ({ children }) => children, code: ({ children }) => children, line: ({ children }) => `${children}`, }, }) } } }) } } function rehypeSlugify() { return (tree) => { let slugify = slugifyWithCounter() visit(tree, 'element', (node) => { if (node.tagName === 'h2' && !node.properties.id) { node.properties.id = slugify(toString(node)) } }) } } function rehypeAddMDXExports(getExports) { return (tree) => { let exports = Object.entries(getExports(tree)) for (let [name, value] of exports) { for (let node of tree.children) { if ( node.type === 'mdxjsEsm' && new RegExp(`export\\s+const\\s+${name}\\s*=`).test(node.value) ) { return } } let exportStr = `export const ${name} = ${value}` tree.children.push({ type: 'mdxjsEsm', value: exportStr, data: { estree: acorn.parse(exportStr, { sourceType: 'module', ecmaVersion: 'latest', }), }, }) } } } function getSections(node) { let sections = [] for (let child of node.children ?? []) { if (child.type === 'element' && child.tagName === 'h2') { sections.push(`{ title: ${JSON.stringify(toString(child))}, id: ${JSON.stringify(child.properties.id)}, ...${child.properties.annotation} }`) } else if (child.children) { sections.push(...getSections(child)) } } return sections } export const rehypePlugins = [ rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'wrap', test: ['h2'] }], [ remarkRehypeWrap, { node: { type: 'element', tagName: 'article' }, start: 'element[tagName=hr]', transform: (article) => { article.children.splice(0, 1) let heading = article.children.find((n) => n.tagName === 'h2') if (heading) { article.properties = { ...heading.properties, title: toString(heading) } heading.properties = {} } else { article.properties = {} } return article }, }, ], mdxAnnotations.rehype, rehypeParseCodeBlocks, rehypeShiki, rehypeSlugify, rehypeMdxTitle, [ rehypeAddMDXExports, (tree) => ({ sections: `[${getSections(tree).join()}]`, }), ], ] ================================================ FILE: docs_src/mdx/remark.mjs ================================================ import { mdxAnnotations } from 'mdx-annotations' import remarkGfm from 'remark-gfm' import remarkUnwrapImages from 'remark-unwrap-images' export const remarkPlugins = [ mdxAnnotations.remark, remarkGfm, remarkUnwrapImages, ] ================================================ FILE: docs_src/next.config.mjs ================================================ import nextMDX from '@next/mdx' import { remarkPlugins } from './mdx/remark.mjs' import { rehypePlugins } from './mdx/rehype.mjs' import { recmaPlugins } from './mdx/recma.mjs' const withMDX = nextMDX({ options: { remarkPlugins, rehypePlugins, recmaPlugins, providerImportSource: '@mdx-js/react', }, }) /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'], experimental: { scrollRestoration: true, }, i18n: { locales: ['en', 'zh'], defaultLocale: 'en', localeDetection: false, }, async redirects() { return [ { source: '/documentation', destination: '/documentation/en', permanent: false, }, ] }, } export default withMDX(nextConfig) ================================================ FILE: docs_src/package.json ================================================ { "name": "tailwindui-template", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "browserslist": "defaults, not ie <= 11", "dependencies": { "@algolia/autocomplete-core": "^1.9.3", "@algolia/autocomplete-preset-algolia": "^1.9.3", "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@mapbox/rehype-prism": "^0.8.0", "@mdx-js/loader": "^2.1.5", "@mdx-js/react": "^2.1.5", "@next/mdx": "^13.0.2", "@sindresorhus/slugify": "^2.2.1", "@tailwindcss/typography": "^0.5.4", "@vercel/analytics": "^1.0.2", "algoliasearch": "^4.17.2", "autoprefixer": "^10.4.12", "axios": "^1.4.0", "clsx": "^1.2.1", "fast-glob": "^3.2.11", "feed": "^4.2.2", "focus-visible": "^5.2.0", "framer-motion": "^10.12.16", "highlight.js": "^11.8.0", "mdx-annotations": "^0.1.3", "meilisearch": "^0.33.0", "next": "13.4.2", "next-mdx-remote": "^6.0.0", "next-router-mock": "^0.9.3", "postcss-focus-visible": "^6.0.4", "prism-themes": "^1.9.0", "prismjs": "^1.29.0", "react": "18.2.0", "react-dom": "18.2.0", "react-markdown": "^8.0.7", "recma-import-images": "^0.0.3", "recma-nextjs-static-props": "^1.0.0", "rehype-autolink-headings": "^6.1.1", "rehype-mdx-title": "^2.0.0", "rehype-slug": "^5.1.0", "remark-gfm": "^3.0.1", "remark-rehype-wrap": "^0.0.2", "remark-unwrap-images": "^3.0.1", "shiki": "^0.14.2", "tailwindcss": "^3.3.0", "zustand": "^4.3.8" }, "devDependencies": { "eslint": "8.26.0", "eslint-config-next": "13.0.2", "prettier": "^2.8.7", "prettier-plugin-tailwindcss": "^0.2.6" } } ================================================ FILE: docs_src/postcss.config.js ================================================ module.exports = { plugins: { tailwindcss: {}, 'postcss-focus-visible': { replaceWith: '[data-focus-visible-added]', }, autoprefixer: {}, }, } ================================================ FILE: docs_src/prettier.config.js ================================================ module.exports = { singleQuote: true, semi: false, plugins: [require('prettier-plugin-tailwindcss')], } ================================================ FILE: docs_src/public/funding.json ================================================ { "version": "v1.0.0", "entity": { "type": "individual", "role": "owner", "name": "Sanskar Jethi", "email": "sansyrox@gmail.com", "phone": "", "description": "Sanskar is a FOSS engineer who created Robyn and Starfyre. Sanskar has created software for over half his life and used it for almost all of his.", "webpageUrl": { "url": "https://robyn.tech/" } }, "projects": [ { "guid": "robyn", "name": "robyn", "description": "Robyn is one of the fastest Python web frameworks, which comes with a built in web server and a Rust runtime.", "webpageUrl": { "url": "https://robyn.tech/" }, "repositoryUrl": { "url": "https://github.com/sparckles/Robyn", "wellKnown": "https://github.com/sparckles/Robyn/blob/main/.well-known/funding-manifest-urls" }, "licenses": ["BSD 2-Clause \"Simplified\" License"], "tags": ["programming", "python", "rust", "web", "backend", "async"] } ], "funding": { "channels": [ { "guid": "mybank", "type": "bank", "address": "", "description": "Send me an email to get my bank details" } ], "plans": [ { "guid": "mybank", "status": "active", "name": "Support Maintainer Part Time", "description": "Support the maintainer for his work on Robyn part time.", "amount": 500, "currency": "GBP", "frequency": "monthly", "channels": ["mybank"] }, { "guid": "mybank", "status": "active", "name": "Support Maintainer Full Time", "description": "Support the maintainer for his work on Robyn full time.", "amount": 3000, "currency": "GBP", "frequency": "monthly", "channels": ["mybank"] }, { "guid": "150", "status": "active", "name": " Support Contributor Part Time", "description": "Support for one contributor per month", "amount": 150, "currency": "GBP", "frequency": "monthly", "channels": ["mybank"] }, { "guid": "500", "status": "active", "name": " Support Contributor Full Time", "description": "Support for one contributor per month", "amount": 500, "currency": "GBP", "frequency": "monthly", "channels": ["mybank"] } ], "history": [] } } ================================================ FILE: docs_src/public/llms.txt ================================================ # Robyn > Robyn is a high-performance, community-driven, and innovator-friendly async web framework for Python with a Rust runtime. It combines Python's ease of use with Rust's performance. ## Quick Facts - Version: 0.79.0 - Python: >= 3.10 - License: BSD 2.0 - Repository: https://github.com/sparckles/robyn - Documentation: https://robyn.tech/documentation - Discord: https://discord.gg/rkERZ5eNU8 ## Installation ```bash pip install robyn ``` ## Basic Usage ```python from robyn import Robyn app = Robyn(__file__) @app.get("/") async def index(request): return "Hello, World!" app.start(port=8080) ``` ## Key Features - **Rust Runtime**: Core server written in Rust using actix-web for high performance - **Async/Sync Support**: Both async and sync route handlers supported - **Multi-Process Scaling**: Built-in multiprocess execution via `--processes` and `--workers` - **WebSockets**: Native WebSocket support - **Middlewares**: Before/after request middlewares - **Dependency Injection**: Built-in DI system - **OpenAPI/Swagger**: Automatic OpenAPI documentation generation - **Hot Reloading**: Development mode with `--dev` flag - **AI Agents**: Built-in AI agent routing via `robyn.ai` - **MCP Support**: Model Context Protocol server capabilities via `app.mcp` - **Templating**: Jinja2 templating support (optional) - **CORS**: Built-in CORS helper via `ALLOW_CORS()` - **Authentication**: AuthenticationHandler base class for custom auth - **Static Files**: Directory serving via `app.serve_directory()` - **SSE**: Server-Sent Events support via `SSEResponse` - **Easy Access Parameters**: Typed path/query params with automatic coercion in handler signatures - **Direct Rust Integration**: Embed Rust code directly in routes ## Project Structure ``` robyn/ ├── src/ # Rust source code │ ├── lib.rs # PyO3 module entry point │ ├── server.rs # Main HTTP server implementation │ ├── types/ # Request, Response, Headers, Cookie types │ ├── routers/ # HTTP, WebSocket, middleware routers │ ├── executors/ # Route execution handlers │ └── websockets/ # WebSocket implementation ├── robyn/ # Python package │ ├── __init__.py # Main Robyn and SubRouter classes │ ├── router.py # Python router implementation │ ├── authentication.py # AuthenticationHandler │ ├── dependency_injection.py │ ├── openapi.py # OpenAPI generation │ ├── mcp.py # MCP protocol support │ ├── ai.py # AI agent support │ ├── responses.py # Response helpers (serve_file, html, SSE) │ ├── ws.py # WebSocket class │ └── robyn.pyi # Type stubs ├── integration_tests/ # Integration test suite ├── unit_tests/ # Unit test suite ├── docs_src/ # Documentation (Next.js) ├── granian/ # Bundled Granian server (fork) └── examples/ # Example applications ``` ## Core Classes ### Robyn / SubRouter Main application class and sub-router for modular routes. ```python from robyn import Robyn, SubRouter app = Robyn(__file__) api = SubRouter(__file__, prefix="/api") @api.get("/users") def get_users(request): return {"users": []} app.include_router(api) ``` ### Request Object ```python request.method # HTTP method request.url # Url object (scheme, host, path) request.headers # Headers dict-like request.query_params # QueryParams request.path_params # Dict of URL params request.body # Raw bytes request.json() # Parse JSON body request.form_data # Multipart form data request.ip_addr # Client IP request.identity # Identity (if authenticated) ``` ### Response Object ```python from robyn import Response Response( status_code=200, headers={"Content-Type": "application/json"}, description="body content" # or body bytes ) ``` ### Decorators ```python @app.get("/path") @app.post("/path") @app.put("/path") @app.delete("/path") @app.patch("/path") @app.head("/path") @app.options("/path") @app.before_request("/path") # Middleware before @app.after_request("/path") # Middleware after @app.startup_handler # Server startup @app.shutdown_handler # Server shutdown ``` ### WebSockets ```python from robyn import WebSocketDisconnect @app.websocket("/ws") async def handler(websocket): try: while True: msg = await websocket.receive_text() await websocket.send_text(f"Echo: {msg}") except WebSocketDisconnect: pass @handler.on_connect def on_connect(websocket): return "Connected" @handler.on_close def on_close(websocket): return "Closed" ``` ### Easy Access Parameters Declare typed path and query parameters directly in handler signatures. Works for both HTTP and WebSocket handlers. ```python from typing import List, Optional # HTTP: path params + query params with type coercion @app.get("/items/:id") async def get_item(id: int, q: str, page: int = 1): return {"id": id, "q": q, "page": page} # Optional, List, and bool params @app.get("/search") def search(name: str, tags: List[str], active: bool = False, age: Optional[int] = None): return {"name": name, "tags": tags, "active": active, "age": age} # WebSocket: typed query params on handler and callbacks @app.websocket("/ws") async def handler(websocket, room: str = "default", page: int = 1): while True: msg = await websocket.receive_text() await websocket.send_text(f"room={room} page={page} msg={msg}") @handler.on_connect def on_connect(websocket, room: str = "default"): return f"connected to {room}" ``` ### MCP (Model Context Protocol) ```python @app.mcp.resource("time://current") def get_time(): return datetime.now().isoformat() @app.mcp.tool(name="calc", description="Calculate", input_schema={...}) def calculate(args): return eval(args["expression"]) @app.mcp.prompt(name="explain", description="Explain code", arguments=[...]) def explain_prompt(args): return f"Please explain: {args['code']}" ``` ## CLI Commands ```bash python app.py # Start server python app.py --dev # Development mode (hot reload) python app.py --processes 4 # Multi-process python app.py --workers 2 # Workers per process python app.py --log-level DEBUG # Log level python app.py --open-browser # Open browser on start python app.py --create # Create new project scaffold python app.py --docs # Open documentation ``` ## Development Setup ```bash # Clone git clone https://github.com/sparckles/robyn.git cd robyn # Virtual environment python3 -m venv .venv && source .venv/bin/activate # Install tools pip install pre-commit poetry maturin # Install dependencies poetry install --with dev --with test # Build Rust extension maturin develop # Run tests pytest ``` ## Key Dependencies - **PyO3**: Rust-Python bindings - **actix-web**: Rust HTTP server (via cookie crate) - **orjson**: Fast JSON serialization - **multiprocess**: Multi-process support - **uvloop**: Fast event loop (non-Windows) - **watchdog**: File watching for hot reload ## Configuration Environment variables: - `ROBYN_HOST`: Server host (default: 127.0.0.1) - `ROBYN_PORT`: Server port (default: 8080) - `ROBYN_DEV_MODE`: Enable dev mode - `ROBYN_BROWSER_OPEN`: Open browser on start - `ROBYN_CLIENT_TIMEOUT`: Client timeout seconds - `ROBYN_KEEP_ALIVE_TIMEOUT`: Keep-alive timeout ## Documentation Structure Main docs at `docs_src/src/pages/documentation/`: - `api_reference/getting_started.mdx` - Quick start guide - `api_reference/request_object.mdx` - Request handling - `api_reference/middlewares.mdx` - Middleware usage - `api_reference/websockets.mdx` - WebSocket guide - `api_reference/authentication.mdx` - Auth patterns - `api_reference/openapi.mdx` - OpenAPI docs - `api_reference/agents.mdx` - AI agent integration - `api_reference/mcps.mdx` - MCP server guide - `example_app/` - Full example application tutorial ================================================ FILE: docs_src/src/components/Button.jsx ================================================ import Link from 'next/link' import clsx from 'clsx' const variantStyles = { primary: 'font-semibold text-zinc-100 bg-zinc-700 hover:bg-zinc-600 active:bg-zinc-700 active:text-zinc-100/70', secondary: 'font-medium bg-zinc-800/50 text-zinc-300 hover:bg-zinc-800 hover:text-zinc-50 active:bg-zinc-800/50 active:text-zinc-50/70', } export function Button({ variant = 'primary', className, href, ...props }) { className = clsx( 'inline-flex items-center gap-2 justify-center rounded-md py-2 px-3 text-sm outline-offset-2 transition active:transition-none', variantStyles[variant], className ) return href ? ( ) : ( ) } export function Footer() { return ( <>

Home Documentation Releases Community Discord

© {new Date().getFullYear()} Sparckles OSS. All rights reserved.

) } ================================================ FILE: docs_src/src/components/Header.jsx ================================================ import { Fragment, useEffect, useRef, useState } from 'react' import Image from 'next/image' import Link from 'next/link' import { useRouter } from 'next/router' import { Popover, Transition } from '@headlessui/react' import clsx from 'clsx' import { Container } from '@/components/Container' import robynLogo from '@/images/robyn_logo.jpg' import { MobileSearch, Search } from '@/components/documentation/Search' function CloseIcon(props) { return ( ) } function ChevronDownIcon(props) { return ( ) } function MobileNavItem({ href, children }) { return (
  • {children}
  • ) } function MobileNavigation(props) { return ( Menu

    Navigation

    ) } function NavItem({ href, children, ...props }) { let isActive = useRouter().pathname === href return (
  • {children} {isActive && ( )}
  • ) } function DesktopNavigation(props) { return ( ) } function GitHubStars() { const [stars, setStars] = useState('6.1k') const [loading, setLoading] = useState(false) const fetchStars = async () => { if (loading) return setLoading(true) try { const response = await fetch('https://api.github.com/repos/sparckles/robyn') const data = await response.json() if (data.stargazers_count) { const count = data.stargazers_count const formatted = count >= 1000 ? `${(count / 1000).toFixed(1)}k` : count.toString() setStars(formatted) } } catch (error) { console.error('Failed to fetch GitHub stars:', error) } finally { setLoading(false) } } useEffect(() => { fetchStars() const interval = setInterval(fetchStars, 300000) return () => clearInterval(interval) }, []) return ( {stars} ) } function clamp(number, a, b) { let min = Math.min(a, b) let max = Math.max(a, b) return Math.min(Math.max(number, min), max) } function Avatar({ large = false, className, ...props }) { return ( ) } export function Header() { let isHomePage = useRouter().pathname === '/' let headerRef = useRef() let avatarRef = useRef() let isInitial = useRef(true) useEffect(() => { let downDelay = avatarRef.current?.offsetTop ?? 0 let upDelay = 64 function setProperty(property, value) { document.documentElement.style.setProperty(property, value) } function removeProperty(property) { document.documentElement.style.removeProperty(property) } function updateHeaderStyles() { let { top, height } = headerRef.current.getBoundingClientRect() let scrollY = clamp( window.scrollY, 0, document.body.scrollHeight - window.innerHeight ) if (isInitial.current) { setProperty('--header-position', 'sticky') } setProperty('--content-offset', `${downDelay}px`) if (isInitial.current || scrollY < downDelay) { setProperty('--header-height', `${downDelay + height}px`) setProperty('--header-mb', `${-downDelay}px`) } else if (top + height < -upDelay) { let offset = Math.max(height, scrollY - upDelay) setProperty('--header-height', `${offset}px`) setProperty('--header-mb', `${height - offset}px`) } else if (top === 0) { setProperty('--header-height', `${scrollY + height}px`) setProperty('--header-mb', `${-scrollY}px`) } if (top === 0 && scrollY > 0 && scrollY >= downDelay) { setProperty('--header-inner-position', 'fixed') removeProperty('--header-top') removeProperty('--avatar-top') } else { removeProperty('--header-inner-position') setProperty('--header-top', '0px') setProperty('--avatar-top', '0px') } } function updateStyles() { updateHeaderStyles() isInitial.current = false } updateStyles() window.addEventListener('scroll', updateStyles, { passive: true }) window.addEventListener('resize', updateStyles) return () => { window.removeEventListener('scroll', updateStyles) window.removeEventListener('resize', updateStyles) } }, [isHomePage]) return ( <>
    {}
    {isHomePage &&
    } ) } ================================================ FILE: docs_src/src/components/Prose.jsx ================================================ import clsx from 'clsx' export function Prose({ children, className }) { return
    {children}
    } ================================================ FILE: docs_src/src/components/Section.jsx ================================================ import { useId } from 'react' export function Section({ title, children }) { let id = useId() return (

    {title}

    {children}
    ) } ================================================ FILE: docs_src/src/components/SimpleLayout.jsx ================================================ import { Container } from '@/components/Container' export function SimpleLayout({ title, intro, children }) { return (

    {title}

    {intro}

    {children}
    ) } ================================================ FILE: docs_src/src/components/SocialIcons.jsx ================================================ export function TwitterIcon(props) { return ( ) } export function InstagramIcon(props) { return ( ) } export function GitHubIcon(props) { return ( ) } export function LinkedInIcon(props) { return ( ) } export function DiscordIcon(props) { return ( ) } ================================================ FILE: docs_src/src/components/Testimonials.jsx ================================================ import { useEffect } from 'react' let testimonials = [ { body: "Robyn has revolutionized the way I develop web solutions. Its seamless integration of Python's async capabilities with a Rust runtime not only ensures reliability and scalability but also provides quick project setup, a delightful user experience, and robust plugin support. With its exceptional speed and multithreaded efficiency, Robyn's real-time communication through WebSockets and dynamic URL routing has empowered me to create highly performant and interactive applications while maintaining full control over navigation and workflows. A game-changer for modern web development!", author: { name: 'Kunal Kushwaha', handle: 'kunalstwt', imageUrl: '/testimonials/kunalstwt.jpg', title: 'DevRel manager at Civo', }, }, { body: "Having worked with a company building a Rust based open source search engine for over a year, I strongly believe in the notion that rewriting software with Rust can significantly improve software performance. Sanskar's idea to recreate Flask with Rust, was just incredible. Having used Robyn myself, it is refreshing to see such a performant Python framework and just the amazing developer ecosystem around it. Yes it still new and being developed, but I can say this with confidence that given the underlying Rust-based multithreaded run time will provide immense performance for running high throughout applications. I am glad to be one of the early sponsors and adopters for Robyn!", author: { name: 'Shivay Lamba', handle: 'howdevelop', imageUrl: '/testimonials/howdevelop.jpg', title: 'Developer Experience Engineer at MeiliSearch', }, }, { body: "I'm impressed with Robyn. It's a fast asynchronous web framework for the Python ecosystem that's built on top of Rust. The syntax is similar to other popular web frameworks, so it's easy to learn and be productive with. I've been using it to build web applications and services, and I'm really happy with the results. I'm also impressed with the Robyn community. They are very supportive and the developers are very responsive to feedback", author: { name: 'Carlos A. Marcano Vargas', handle: 'carlos_marcv', imageUrl: '/testimonials/carlos_marcv.jpg', title: 'Technical Writer', }, }, // More testimonials... { body: 'Great to see a Community Driven Open Source project, achieve new heights! Robyn is built by the community for the community', author: { name: 'Eddie Jaoude', handle: 'eddiejaoude', imageUrl: '/testimonials/eddiejaoude.jpg', title: 'Creator of EddieHub', }, }, // More testimonials... { body: 'I used to be a Batman fan, but having met Robyn I now think the sidekick has become the hero. Free, OSS, straight forward and powerful, what is not to love?', author: { name: 'GrahamTheDev', handle: 'GrahamTheDev', imageUrl: '/testimonials/GrahamTheDev.jpg', title: 'The Accessibility First DevRel ', }, }, { body: 'Having used both, Flask and Django for writing web applications in Python in the past, Robyn looks like their combined successor in terms of ergonomics and features available. Its reliance on a Rust runtime for performance and security is the cherry on the cake!', author: { name: 'Daniel Bodky', handle: 'd_bodky', imageUrl: '/testimonials/d_bodky.jpg', title: 'Consultant, Trainer, Speaker @NETWAYS', }, }, // More testimonials... { body: 'Robyn has made a big difference in my projects. Its flexible structure allows my work to adapt smoothly to my needs, even when I face complex challenges. The community-driven and open-source nature of Robyn makes it a welcoming place for developers like me. Plus, its simple yet powerful API has greatly streamlined my development process, reducing my wor oad. I highly recommend it!', author: { name: 'Julia Furst Morgado', handle: 'juliafmorgado', imageUrl: '/testimonials/juliafmorgado.jpg', title: 'Global technologist @Veeam', }, }, // More testimonials... { body: 'Robyn opens a new chapter in the Python web frameworks scene: the Rust powered one, where performance and safety are not the sole protagonists.', author: { name: 'Giovanni Barillari', handle: 'gi0baro', imageUrl: '/testimonials/gi0baro.jpeg', title: 'Author of Granian and Emmett', }, }, // More testimonials... { body: "I collaborate with Robyn's team and I must say, Sanskar does an excellent job maintaining the community. The project as a whole is immensely beneficial, both for collaboration and its practical uses. The tool is impressive, easy to use and the entire community is very welcoming to first-time contributors", author: { name: 'Jyoti Bisht', handle: 'joeyousss', imageUrl: '/testimonials/joeyousss.jpg', title: 'Open Source Developer', }, }, // More testimonials... { body: "Robyn is a breath of fresh air in web development. Merging Python's simplicity with Rust's speed, it offers a seamless experience for developers. Its features are precisely what today's web projects need. I'm particularly impressed with its community focus; it's evident that everyone's voice matters in shaping Robyn's journey. In a sea of web frameworks, Robyn stands out not just for its tech but also for its heart.", author: { name: 'Francesco Ciulla', handle: 'FrancescoCiull4', imageUrl: '/testimonials/FrancescoCiull4.jpg', title: 'DevRel at daily.dev', }, }, // More testimonials... ] //shuflle testimonials function classNames(...classes) { return classes.filter(Boolean).join(' ') } const chunk = (arr, size) => Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(i * size, i * size + size) ) export default function Testimonials() { let chunkedTestimonials = []; // Separate testimonials into groups of 3, 4, and 3 const firstGroup = chunk(testimonials.slice(0, 3), 3); const secondGroup = chunk(testimonials.slice(3, 7), 4); const thirdGroup = chunk(testimonials.slice(7), 3); // Concatenate the groups in the desired order chunkedTestimonials = firstGroup.concat(secondGroup, thirdGroup); return (