Skip to content

Commit

Permalink
Merge branch 'main' into feat/add-mi-malloc
Browse files Browse the repository at this point in the history
  • Loading branch information
sansyrox authored Sep 7, 2023
2 parents 9e8803a + 62b285f commit c3be01c
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 45 deletions.
16 changes: 2 additions & 14 deletions .github/workflows/preview-deployments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,8 @@ jobs:
{ version: "3.10", abi: "cp310-cp310" },
{ version: "3.11", abi: "cp311-cp311" },
]
manylinux: [auto]
include:
- os: ubuntu
platform: linux
target: aarch64
container: messense/manylinux_2_24-cross:aarch64
- os: ubuntu
platform: linux
target: x86_64
manylinux: musllinux_1_1
- os: ubuntu
platform: linux
target: aarch64
manylinux: musllinux_1_1

target: [aarch64, armv7]
steps:
- uses: actions/checkout@v3
- name: Build Wheels
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "robyn"
version = "0.38.0"
version = "0.39.0"
authors = ["Sanskar Jethi <[email protected]>"]
edition = "2018"
description = "A web server that is fast!"
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

[![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/sansyrox/robyn?include_prereleases=&sort=semver&color=black)](https://github.com/sansyrox/robyn/releases/)
[![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)](#license)
![Python](https://img.shields.io/badge/Support-Version%20%E2%89%A5%203.7-brightgreen)
![Python](https://img.shields.io/badge/Support-Version%20%E2%89%A5%203.8-brightgreen)

[![view - Documentation](https://img.shields.io/badge/view-Documentation-blue?style=for-the-badge)](https://sansyrox.github.io/robyn/#/)
[![view - Documentation](https://img.shields.io/badge/view-Documentation-blue?style=for-the-badge)](https://sparckles.github.io/robyn/#/)
[![Discord](https://img.shields.io/discord/999782964143603713?label=discord&logo=discord&logoColor=white&style=for-the-badge&color=blue)](https://discord.gg/rkERZ5eNU8)

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://sansyrox.github.io/robyn/#/community-resources)!
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://sparckles.github.io/robyn/#/community-resources)!

## 📦 Installation

Expand Down Expand Up @@ -77,7 +77,7 @@ $ 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/sansyrox/robyn/blob/main/integration_tests/base_routes.py) as examples.
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

Expand Down Expand Up @@ -114,10 +114,10 @@ python --version

### 🏁 Get started

Please read the [code of conduct](https://github.com/sansyrox/robyn/blob/main/CODE_OF_CONDUCT.md) and go through [CONTRIBUTING.md](https://github.com/sansyrox/robyn/blob/main/CONTRIBUTING.md) before contributing to Robyn.
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://sansyrox.github.io/robyn/#/architecture).
If you're feeling curious. You can take a look at a more detailed architecture [here](https://sparckles.github.io/robyn/#/architecture).

If you still need help to get started, feel free to reach out on our [community discord](https://discord.gg/rkERZ5eNU8).

Expand All @@ -142,8 +142,8 @@ curl http://localhost:8080/sync/str

Thanks to all the contributors of the project. Robyn will not be what it is without all your support :heart:.

<a href="https://github.com/sansyrox/robyn/graphs/contributors">
<img src="https://contrib.rocks/image?repo=sansyrox/robyn" />
<a href="https://github.com/sparckles/robyn/graphs/contributors">
<img src="https://contrib.rocks/image?repo=sparckles/robyn" />
</a>

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. 💖
Expand All @@ -159,4 +159,4 @@ These sponsors help us make the magic happen!

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=sansyrox/robyn&type=Date)](https://star-history.com/#sansyrox/robyn&Date)
[![Star History Chart](https://api.star-history.com/svg?repos=sparckles/robyn&type=Date)](https://star-history.com/#sparckles/robyn&Date)
12 changes: 12 additions & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,18 @@ app.add_view("/", View)

```

## Route Registration

Instead of using the decorators, you can also add routes with a function:

```python
async def hello(request):
return "Hello World"

app.add_route("GET", "/hello", hello)
```

This works for all HTTP methods.

## Allow CORS

Expand Down
31 changes: 29 additions & 2 deletions docs/plugins.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
## Plugin Design

Robyn is an extensible web framework that allows anyone to make plugins over the top of Robyn.
Robyn is a versatile and extensible web framework that allows anyone to make plugins over the top of Robyn.
Plugins in Robyn allow you to enhance and customize the framework's functionality to suit your specific needs. Here are some noteworthy plugins that can supercharge your Robyn-based projects:

### Tutorial coming soon..
### Rate Limit Plugin
- Description: This plugin enables you to implement rate limiting for your Robyn application's routes. It helps prevent abuse, and brute-force attacks and ensures fair usage of your resources.
- GitHub repository: [robyn-rate-limits](https://github.com/IdoKendo/robyn_rate_limits)
- Installation:
`python -m pip install robyn-rate-limits`
- Usage:
```py
from robyn import Robyn
from robyn_rate_limits import InMemoryStore
from robyn_rate_limits import RateLimiter

app = Robyn(__file__)
limiter = RateLimiter(store=InMemoryStore, calls_limit=3, limit_ttl=100)

@app.before_request()
def middleware(request: Request):
return limiter.handle_request(app, request)

@app.get("/")
def h():
return "Hello, World!"

app.start(port=8080)
```
In this example, robyn-rate-limits is used to enforce a rate limit of 3 requests per 100-seconds window for specific routes. If a client exceeds this limit, they will receive a "Too many requests" message.

The plugin integrates seamlessly with the Robyn web framework, enhancing the security and stability of your application by preventing excessive requests from a single client.
28 changes: 27 additions & 1 deletion integration_tests/base_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
from collections import defaultdict
from typing import Optional

from robyn import WS, Robyn, Request, Response, jsonify, serve_file, serve_html
from robyn import (
Request,
Response,
Robyn,
WS,
jsonify,
serve_file,
serve_html,
)
from robyn.authentication import AuthenticationHandler, BearerGetter, Identity
from robyn.templating import JinjaTemplate

Expand Down Expand Up @@ -714,6 +722,24 @@ async def async_auth(request: Request):
# ===== Main =====


def sync_without_decorator():
return "Success!"


async def async_without_decorator():
return "Success!"


app.add_route("GET", "/sync/get/no_dec", sync_without_decorator)
app.add_route("PUT", "/sync/put/no_dec", sync_without_decorator)
app.add_route("POST", "/sync/post/no_dec", sync_without_decorator)
app.add_route("GET", "/async/get/no_dec", async_without_decorator)
app.add_route("PUT", "/async/put/no_dec", async_without_decorator)
app.add_route("POST", "/async/post/no_dec", async_without_decorator)

# ===== Main =====


def main():
app.add_response_header("server", "robyn")
app.add_directory(
Expand Down
21 changes: 21 additions & 0 deletions integration_tests/test_add_route_without_decorator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from collections.abc import Callable
import pytest
from integration_tests.helpers.http_methods_helpers import get, post, put


@pytest.mark.benchmark
@pytest.mark.usefixtures("session")
@pytest.mark.parametrize(
"route,method",
[
("/sync/get/no_dec", get),
("/async/get/no_dec", get),
("/sync/put/no_dec", put),
("/async/put/no_dec", put),
("/sync/post/no_dec", post),
("/async/post/no_dec", post),
],
)
def test_exception_handling(route: str, method: Callable):
r = method(route, expected_status_code=200)
assert r.text == "Success!"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "robyn"
version = "0.38.0"
version = "0.39.0"
description = "A High-Performance, Community-Driven, and Innovator Friendly Web Framework with a Rust runtime."
authors = [{ name = "Sanskar Jethi", email = "[email protected]" }]
repository = "https://github.com/sparckles/robyn"
Expand Down
48 changes: 33 additions & 15 deletions robyn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import multiprocess as mp
import os
from typing import Callable, List, Optional, Tuple
from typing import Callable, List, Optional, Tuple, Union
from nestd import get_all_nested


Expand All @@ -15,7 +15,14 @@
from robyn.logger import logger
from robyn.processpool import run_processes
from robyn.responses import serve_file, serve_html
from robyn.robyn import FunctionInfo, HttpMethod, Request, Response, get_version, jsonify
from robyn.robyn import (
FunctionInfo,
HttpMethod,
Request,
Response,
get_version,
jsonify,
)
from robyn.router import MiddlewareRouter, MiddlewareType, Router, WebSocketRouter
from robyn.types import Directory, Header
from robyn import status_codes
Expand Down Expand Up @@ -58,16 +65,16 @@ def __init__(self, file_object: str, config: Config = Config()) -> None:
self.exception_handler: Optional[Callable] = None
self.authentication_handler: Optional[AuthenticationHandler] = None

def _add_route(
def add_route(
self,
route_type: HttpMethod,
route_type: Union[HttpMethod, str],
endpoint: str,
handler: Callable,
is_const: bool = False,
auth_required: bool = False,
):
"""
This is base handler for all the route decorators
Connect a URI to a handler
:param route_type str: route type between GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/TRACE
:param endpoint str: endpoint for the route added
Expand All @@ -80,6 +87,17 @@ def _add_route(
"""
if auth_required:
self.middleware_router.add_auth_middleware(endpoint)(handler)
if isinstance(route_type, str):
http_methods = {
"GET": HttpMethod.GET,
"POST": HttpMethod.POST,
"PUT": HttpMethod.PUT,
"DELETE": HttpMethod.DELETE,
"PATCH": HttpMethod.PATCH,
"HEAD": HttpMethod.HEAD,
"OPTIONS": HttpMethod.OPTIONS,
}
route_type = http_methods[route_type]

return self.router.add_route(
route_type, endpoint, handler, is_const, self.exception_handler
Expand Down Expand Up @@ -205,7 +223,7 @@ def get_functions(view) -> List[Tuple[HttpMethod, Callable]]:

handlers = get_functions(view)
for route_type, handler in handlers:
self._add_route(route_type, endpoint, handler, const)
self.add_route(route_type, endpoint, handler, const)

def view(self, endpoint: str, const: bool = False):
"""
Expand All @@ -227,7 +245,7 @@ def get(self, endpoint: str, const: bool = False, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.GET, endpoint, handler, const, auth_required
)

Expand All @@ -241,7 +259,7 @@ def post(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.POST, endpoint, handler, auth_required=auth_required
)

Expand All @@ -255,7 +273,7 @@ def put(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.PUT, endpoint, handler, auth_required=auth_required
)

Expand All @@ -269,7 +287,7 @@ def delete(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.DELETE, endpoint, handler, auth_required=auth_required
)

Expand All @@ -283,7 +301,7 @@ def patch(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.PATCH, endpoint, handler, auth_required=auth_required
)

Expand All @@ -297,7 +315,7 @@ def head(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.HEAD, endpoint, handler, auth_required=auth_required
)

Expand All @@ -311,7 +329,7 @@ def options(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.OPTIONS, endpoint, handler, auth_required=auth_required
)

Expand All @@ -325,7 +343,7 @@ def connect(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.CONNECT, endpoint, handler, auth_required=auth_required
)

Expand All @@ -339,7 +357,7 @@ def trace(self, endpoint: str, auth_required: bool = False):
"""

def inner(handler):
return self._add_route(
return self.add_route(
HttpMethod.TRACE, endpoint, handler, auth_required=auth_required
)

Expand Down

0 comments on commit c3be01c

Please sign in to comment.