Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Event handlers #154

Merged
merged 6 commits into from
Jan 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions integration_tests/base_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,34 @@
import asyncio
import os
import pathlib
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Robyn(__file__)
websocket = WS(app, "/web_socket")
i = -1


@websocket.on("message")
async def connect():
global i
i+=1
if i==0:
i += 1
if i == 0:
return "Whaaat??"
elif i==1:
elif i == 1:
return "Whooo??"
elif i==2:
elif i == 2:
i = -1
return "*chika* *chika* Slim Shady."


@websocket.on("close")
def close():
return "GoodBye world, from ws"


@websocket.on("connect")
def message():
return "Hello world, from ws"
Expand All @@ -35,7 +42,7 @@ def message():
async def hello(request):
global callCount
callCount += 1
message = "Called " + str(callCount) + " times"
_message = "Called " + str(callCount) + " times"
return jsonify(request)


Expand All @@ -47,10 +54,12 @@ async def test(request):

return static_file(html_file)


@app.get("/jsonify")
async def json_get():
return jsonify({"hello": "world"})


@app.get("/query")
async def query_get(request):
query_data = request["queries"]
Expand All @@ -62,18 +71,22 @@ async def json(request):
print(request["params"]["id"])
return jsonify({"hello": "world"})


@app.post("/post")
async def post():
return "POST Request"


@app.post("/post_with_body")
async def postreq_with_body(request):
return bytearray(request["body"]).decode("utf-8")


@app.put("/put")
async def put(request):
return "PUT Request"


@app.put("/put_with_body")
async def putreq_with_body(request):
print(request)
Expand All @@ -84,6 +97,7 @@ async def putreq_with_body(request):
async def delete():
return "DELETE Request"


@app.delete("/delete_with_body")
async def deletereq_with_body(request):
return bytearray(request["body"]).decode("utf-8")
Expand All @@ -93,6 +107,7 @@ async def deletereq_with_body(request):
async def patch():
return "PATCH Request"


@app.patch("/patch_with_body")
async def patchreq_with_body(request):
return bytearray(request["body"]).decode("utf-8")
Expand All @@ -107,14 +122,29 @@ async def sleeper():
@app.get("/blocker")
def blocker():
import time

time.sleep(10)
return "blocker function"


async def startup_handler():
logger.log(logging.INFO, "Starting up")


@app.shutdown_handler
def shutdown_handler():
logger.log(logging.INFO, "Shutting down")


if __name__ == "__main__":
ROBYN_URL = os.getenv("ROBYN_URL", '0.0.0.0')
ROBYN_URL = os.getenv("ROBYN_URL", "0.0.0.0")
app.add_header("server", "robyn")
current_file_path = pathlib.Path(__file__).parent.resolve()
os.path.join(current_file_path, "build")
app.add_directory(route="/test_dir",directory_path=os.path.join(current_file_path, "build/"), index_file="index.html")
app.add_directory(
route="/test_dir",
directory_path=os.path.join(current_file_path, "build/"),
index_file="index.html",
)
app.startup_handler(startup_handler)
app.start(port=5000, url=ROBYN_URL)
14 changes: 9 additions & 5 deletions integration_tests/test_get_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@

BASE_URL = "http://127.0.0.1:5000"


def test_index_request(session):
res = requests.get(f"{BASE_URL}")
assert(res.status_code == 200)
assert res.status_code == 200


def test_jsonify(session):
r = requests.get(f"{BASE_URL}/jsonify")
assert r.json()=={"hello":"world"}
assert r.status_code==200
assert r.json() == {"hello": "world"}
assert r.status_code == 200


def test_html(session):
r = requests.get(f"{BASE_URL}/test/123")
assert "Hello world. How are you?" in r.text


def test_queries(session):
r = requests.get(f"{BASE_URL}/query?hello=robyn")
assert r.json()=={"hello":"robyn"}
assert r.json() == {"hello": "robyn"}

r = requests.get(f"{BASE_URL}/query")
assert r.json()=={}
assert r.json() == {}
75 changes: 53 additions & 22 deletions robyn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import asyncio
from inspect import signature
import multiprocessing as mp
from robyn.events import Events

# custom imports and exports
from .robyn import Server, SocketHeld
Expand All @@ -21,13 +22,12 @@


class Robyn:
"""This is the python wrapper for the Robyn binaries.
"""
"""This is the python wrapper for the Robyn binaries."""

def __init__(self, file_object):
directory_path = os.path.dirname(os.path.abspath(file_object))
self.file_path = file_object
self.directory_path = directory_path
self.server = Server(directory_path)
self.parser = ArgumentParser()
self.dev = self.parser.is_dev()
self.processes = self.parser.num_processes()
Expand All @@ -37,6 +37,7 @@ def __init__(self, file_object):
self.routes = []
self.directories = []
self.web_sockets = {}
self.event_handlers = {}

def add_route(self, route_type, endpoint, handler):
"""
Expand All @@ -51,25 +52,41 @@ def add_route(self, route_type, endpoint, handler):
"""
number_of_params = len(signature(handler).parameters)
self.routes.append(
(route_type,
endpoint,
handler,
asyncio.iscoroutinefunction(handler), number_of_params)
(
route_type,
endpoint,
handler,
asyncio.iscoroutinefunction(handler),
number_of_params,
)
)

def add_directory(self, route, directory_path, index_file=None, show_files_listing=False):
def add_directory(
self, route, directory_path, index_file=None, show_files_listing=False
):
self.directories.append((route, directory_path, index_file, show_files_listing))

def add_header(self, key, value):
self.headers.append((key, value))

def remove_header(self, key):
self.server.remove_header(key)

def add_web_socket(self, endpoint, ws):
self.web_sockets[endpoint] = ws

def start(self, url="127.0.0.1", port=5000):
def _add_event_handler(self, event_type: str, handler):
print(f"Add event {event_type} handler")
if event_type not in {Events.STARTUP, Events.SHUTDOWN}:
return

is_async = asyncio.iscoroutinefunction(handler)
self.event_handlers[event_type] = (handler, is_async)

def startup_handler(self, handler):
self._add_event_handler(Events.STARTUP, handler)

def shutdown_handler(self, handler):
self._add_event_handler(Events.SHUTDOWN, handler)

def start(self, url="128.0.0.1", port=5000):
"""
[Starts the server]

Expand All @@ -78,25 +95,31 @@ def start(self, url="127.0.0.1", port=5000):
if not self.dev:
workers = self.workers
socket = SocketHeld(url, port)
for process_number in range(self.processes):
copied = socket.try_clone()
for _ in range(self.processes):
copied_socket = socket.try_clone()
p = Process(
target=spawn_process,
args=(url, port, self.directories, self.headers,
self.routes, self.web_sockets, copied,
f"Process {process_number}", workers),
args=(
self.directories,
self.headers,
self.routes,
self.web_sockets,
self.event_handlers,
copied_socket,
workers,
),
)
p.start()

print("Press Ctrl + C to stop \n")
else:
event_handler = EventHandler(self.file_path)
event_handler.start_server_first_time()
print(f"{Colors.OKBLUE}Dev server initialised with the directory_path : {self.directory_path}{Colors.ENDC}")
print(
f"{Colors.OKBLUE}Dev server initialised with the directory_path : {self.directory_path}{Colors.ENDC}"
)
observer = Observer()
observer.schedule(event_handler,
path=self.directory_path,
recursive=True)
observer.schedule(event_handler, path=self.directory_path, recursive=True)
observer.start()
try:
while True:
Expand All @@ -111,6 +134,7 @@ def get(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("GET", endpoint, handler)

Expand All @@ -122,6 +146,7 @@ def post(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("POST", endpoint, handler)

Expand All @@ -133,6 +158,7 @@ def put(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("PUT", endpoint, handler)

Expand All @@ -144,6 +170,7 @@ def delete(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("DELETE", endpoint, handler)

Expand All @@ -155,6 +182,7 @@ def patch(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("PATCH", endpoint, handler)

Expand All @@ -166,6 +194,7 @@ def head(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("HEAD", endpoint, handler)

Expand All @@ -177,6 +206,7 @@ def options(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("OPTIONS", endpoint, handler)

Expand All @@ -188,6 +218,7 @@ def connect(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("CONNECT", endpoint, handler)

Expand All @@ -199,8 +230,8 @@ def trace(self, endpoint):

:param endpoint [str]: [endpoint to server the route]
"""

def inner(handler):
self.add_route("TRACE", endpoint, handler)

return inner

3 changes: 3 additions & 0 deletions robyn/events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Events:
STARTUP = "startup"
SHUTDOWN = "shutdown"
Loading