Skip to content

Latest commit

 

History

History
182 lines (146 loc) · 5.93 KB

README.md

File metadata and controls

182 lines (146 loc) · 5.93 KB

pyroboxCore

A simple and fun server framework to avoid using django and big stuff

Feel Free to Support Me:

Buy Me A Coffee

Usage

  • Import the module
from pyroboxCore import config, logger, SimpleHTTPRequestHandler as SH_base, DealPostData as DPD, run as run_server
* config: A class containing the configuration of the server. Kindly check the code comments for more info.
* logger: Logger module to log stuffs and also supress the logs.
* SimpleHTTPRequestHandler: A class that inherits from BaseHTTPRequestHandler and has some extra features. This is the main class that you will be using.
* DealPostData: A class that uses the SimpleHTTPRequestHandler class functions to deal with post data.
* run: A function that runs the server.
  • Incase you need to change SimpleHTTPRequestHandler methods or funtionality Create a class that inherits from SimpleHTTPRequestHandler and override the methods you want to change. You can check an example in here

  • Lets make our first server

from http import HTTPStatus

from pyroboxCore import config, logger, SimpleHTTPRequestHandler as SH_base, run as run_server

class SH(SH_base):
	"""
		Simply inherits from SimpleHTTPRequestHandler
	"""
	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)

@SH.on_req('HEAD') # HEAD or GET both requests will be handled by this function
def default_get(self: SH, *args, **kwargs):
	"""
		Handles all the GET requests
	"""
	self.send_text(HTTPStatus.OK, "Hello World")


def run():
	run_server(handler=SH, port=8080)
	# this will run the server in current directory at port 8080

if __name__ == '__main__':
	run()
  • So you've seen how it works.

    • NOTE THAT The @SH.on_req decorator acts as switch case for the request type. So make sure to put default case at the end of handlers tree. Also handle 404 errors in the default case.
  • Lets spice it up a bit

from http import HTTPStatus

from pyroboxCore import config, logger, SimpleHTTPRequestHandler as SH_base, run as run_server

class SH(SH_base):
	"""
		Simply inherits from SimpleHTTPRequestHandler
	"""
	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)

@SH.on_req('HEAD', url='/') # HEAD or GET both requests will be handled by this function
def index(self: SH, *args, **kwargs):
	"""
		Handles index page ("/") request only
	"""
	self.send_text(HTTPStatus.OK, "Hello World")

@SH.on_req('HEAD', url='/test') # @SH.on_req has many more args to handle request url and query string. Check the code comments for more info
def test(self: SH, *args, **kwargs):
	"""
		Handles requests to "/test" only
	"""
	self.send_text(HTTPStatus.OK, "This is a test")
	# you can also send json data
	# self.send_json({"test": "This is a test"})

	# or send a file
	# self.send_file("path/to/file")

@SH.on_req('HEAD') # anything other than home and /test will raise 404
def default_get(self: SH, *args, **kwargs):
	"""
		Handles all the other GET requests
	"""
	self.send_error(HTTPStatus.NOT_FOUND, "Page not found")

def run():
	run_server(handler=SH, port=8080)
	# this will run the server in current directory at port 8080

if __name__ == '__main__':
	run()
  • Now lets see how to deal with post data
from http import HTTPStatus

from pyroboxCore import config, logger, SimpleHTTPRequestHandler as SH_base, DealPostData as DPD, run as run_server

class SH(SH_base):
	"""
		Simply inherits from SimpleHTTPRequestHandler
	"""
	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)

@SH.on_req('HEAD')
def default_get(self: SH, *args, **kwargs):
	"""
		Handles all the GET requests
	"""
	return self.send_text(HTTPStatus.OK, """
	<html>
<head>
<title>Post demo</title>
</head>
<body>
	<!-- multipart form -->
	<form action="/post_address" method="post" enctype="multipart/form-data">
		<!-- text field -->
		<label for="text1">Name: </label>
		<input type="text" name="text1" placeholder="Enter Name" />
		</br>
		<label for="text2">Age: </label>
		<input type="text" name="text2" placeholder="Enter Age" />
		</br>
		<input type="submit" value="submit" />
	</form>
</body>

</html>
	""", content_type="text/html; charset=utf-8")

@SH.on_req('POST')
def default_post(self: SH, *args, **kwargs):
	"""
		Handles all the POST requests
	"""
	# you can use the DealPostData class to deal with post data

	post = DPD(self)

	post.start() # start the post data processing
	# this will gather content_length, content_type, boundary from the request headers and reach the end of the headers (and the 1st boundary at line 0)

	n = 1
	while True:
		line = post.get()
		# you can also handle form fields using `post.get_part(verify_name=None, varify_msg=None)`
		# optional `verify_name` and `verify_msg` args can be used to verify the name of the field and the message
		# if not varified, raise `PostError` (this will also cancel the post connection. So you can actually block requests before they even complete) 
		if line is None:
			break
		# do something with the line
		print(f"Line {n}: {line}")
		n += 1
		
	print("The post data is over")


	# you can also send a file/text/json response
	return self.send_text(HTTPStatus.OK, "<b>Post data received</b>", content_type="text/html; charset=utf-8")
	# you can also post process in the function if you just don't want to return anything yet


def run():
	run_server(handler=SH, port=8080)
	# this will run the server in current directory at port 8080

if __name__ == '__main__':
	run()

For more Examples,

Check

  • pyrobox : A remote file manager server
  • AI_girl : A simple chatbot server with messaging interface