Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/a3r0id/sonoma
A tiny, programmable http server crafting framework that is built with security and simplicity in mind.
https://github.com/a3r0id/sonoma
alternative api django easy flask framework http php python server simple socket
Last synced: 23 days ago
JSON representation
A tiny, programmable http server crafting framework that is built with security and simplicity in mind.
- Host: GitHub
- URL: https://github.com/a3r0id/sonoma
- Owner: a3r0id
- License: mit
- Created: 2021-02-12T20:40:21.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2021-03-08T04:55:46.000Z (over 3 years ago)
- Last Synced: 2024-10-04T14:46:55.765Z (about 1 month ago)
- Topics: alternative, api, django, easy, flask, framework, http, php, python, server, simple, socket
- Language: Python
- Homepage:
- Size: 91.8 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Sonoma
[![PyPI version](https://badge.fury.io/py/sonoma.svg)](https://badge.fury.io/py/sonoma)A tiny, low-level, programmable http-server-crafting framework that is built with security and simplicity in mind.
----
![](https://imengine.prod.srp.navigacloud.com/?uuid=C31C28DA-402C-4C02-9083-6C8DACCF1556&type=primary&q=72&width=1024)
----
# Setup
```pip install sonoma```----
# Basic Usage
### Server
```python
from sonoma import httpServerserver = httpServer('127.0.0.1', 8888)
server.run()
```### Browser
```
Hello World!
This is the default webpage for Sonoma/1.0.x.
```----
# Basic Usage: Custom Response
### Server
```python
from sonoma import defaults, httpServerserver = httpServer('127.0.0.1', 8888)
defaults['defaultResponse'] = """
html, body{ margin: 0 auto;text-align:center; }
Hello World!
This is a modified version of the default webpage for %s.
""" % defaults['serverName']server.run()
```### Browser
```
Hello World!
This is a modified version of the default webpage for Sonoma/1.0.12.
```----
# Advanced Usage: Custom Handler
### Server
```python
from sonoma import httpServer, defaults, sonomaPrint
from sonoma import setCookie, parseCookies
from http import HTTPStatus# DEFINES CUSTOM HANDLER
def myHandler(self, REQUEST, CONNECTION):
"""
## Supported Methods:
- GET
- HEAD
"""# UNPACK "REQUEST" TUPLE
requestStatusLine, requestHeaders, requestBody = REQUEST# UNPACK CONNECTION TUPLE
client_connection, client_address = CONNECTION# LOG THE REQUEST TO STDOUT
sonomaPrint("%s -> %s Request: %s" % (str(self.vector), str(client_address), str(requestStatusLine),))
#
# RESOLVE THE REQUEST METHOD AND RESPOND ACCORDINGLY:
#
# SERVE GET
if requestStatusLine.split()[0].lower() == "get":# GET OUR DEFAULT HEADERS + STATUS LINE
responseStatusLine, responseHeaders = self.httpHeaders(HTTPStatus.OK, contentType="html")
# CREATE A LIST OF STRINGS OF EACH REQUEST HEADER FOR USE IN OUR EXAMPLE
headerStrings = ["%s: %s\n" % (header[0], header[1]) for header in requestHeaders]# HERES HOW WE CAN WORK WITH COOKIES, BOTH REQUEST AND RESPONSE:
requestCookies = parseCookies(requestHeaders) # GET REQUEST COOKIES
#sonomaPrint(requestCookies)
setCookie(responseHeaders, "cookieName", "cookieValue", ['Secure', 'HttpOnly']) # SET A RESPONSE COOKIE
#sonomaPrint(responseHeaders)# CREATE A CUSTOM RESPONSE
responseBody = ("""
html, body{ margin: 0 auto;text-align:center; }
Hello World!
This is a custom response from %s.
Request Headers:
%s
""" % (defaults['serverName'], "".join(headerStrings))).encode()
return (responseStatusLine, responseHeaders, responseBody)
# RESPOND WITH 405 STATUS - METHOD NOT ALLOWED
else:
responseStatusLine, responseHeaders = self.httpHeaders(HTTPStatus.METHOD_NOT_ALLOWED, contentType="text")
return (responseStatusLine, responseHeaders, "")# INITIALIZE THE SERVER BUT SET OUR CUSTOM HANDLER BEFORE RUNNING.
server = httpServer('127.0.0.1', 8888)server.set_handler(myHandler)
server.run()
```### Browser
![](https://cdn.discordapp.com/attachments/796917179987656774/809904244387348490/unknown.png)----
# Advanced Handler: JSON API
### Server
```python
from sonoma import httpServer, HTTPStatus, sonomaPrint, serverGmtTime
from json import dumps
from urllib.parse import urlparse, parse_qs# DEFINES CUSTOM HANDLER
def myHandler(self, REQUEST, CONNECTION):
"""
## Supported Methods:
- GET
- HEAD
"""# UNPACK "REQUEST" TUPLE
requestStatusLine, requestHeaders, requestBody = REQUEST# UNPACK CONNECTION TUPLE
client_connection, client_address = CONNECTION# LOG THE REQUEST TO STDOUT
sonomaPrint("%s -> %s Request: %s" % (str(self.vector), str(client_address), str(requestStatusLine),))
#
# RESOLVE THE REQUEST METHOD AND RESPOND ACCORDINGLY:
#
# SERVE GET-JSON
if requestStatusLine.split()[0].lower() == "get":# GET OUR JSON HEADERS + STATUS LINE
responseStatusLine, responseHeaders = self.httpHeaders(HTTPStatus.OK, contentType="json")
# PARSE THE GET QUERY
try:
clientQuery = parse_qs(urlparse(requestStatusLine.split()[1]).query)
except:
# IF QUERY CANNOT BE PARSED THEN RESPOND WITH AN ERROR MESSAGE
return (responseStatusLine, responseHeaders, dumps({'error': 'Invalid url query!'}))# GET TIME FOR ONE OF OUR SERVERSIDE PROCESSING EXAMPLES
tstamp = serverGmtTime()responseBody = dumps({
'query': clientQuery,
'time_gmt': tstamp
}, indent=4)
return (responseStatusLine, responseHeaders, responseBody)
# RESPOND WITH 405 STATUS - METHOD NOT ALLOWED
else:
responseStatusLine, responseHeaders = self.httpHeaders(HTTPStatus.METHOD_NOT_ALLOWED, contentType="text")
return (responseStatusLine, responseHeaders, "")# INITIALIZE THE SERVER BUT SET OUR CUSTOM HANDLER BEFORE RUNNING.
server = httpServer('127.0.0.1', 8888)server.set_handler(myHandler)
server.run()
```
### Browser
> http://127.0.0.1:8888/?testQuery=1
```json
{
"query": {
"testQuery": [
"1"
]
},
"time_gmt": "Sat, 20 Feb 2021 20:18:51 GMT"
}
```
# Conclusion- Adding better documentation soon!