Skip to content

Commit

Permalink
support python 3.7
Browse files Browse the repository at this point in the history
* remove f-string equalities
* from __future__ import annotations
* better README
  • Loading branch information
modularizer committed Feb 1, 2024
1 parent c816a4f commit 2a6f9b1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
84 changes: 80 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# socketwrench
A webserver based on `socket`.

## Quickstart
A webserver based on `socket.socket` with no dependencies other than the standard library.
Provides a lightweight quickstart to make an API which supports OpenAPI, Swagger, and more.

# Quickstart
### Install
```bash
pip install socketwrench
Expand All @@ -24,9 +24,84 @@ if __name__ == '__main__':
# OR
# serve("my_module.MyServer")
```
* Go to http://localhost:8080/hello and see the response "world".
* Now go to http://localhost:8080/swagger to see the Swagger UI.

# Features
## OpenAPI & Swagger
* Go to http://localhost:8080/swagger (after running `serve`) to see the Swagger UI.
* Go to http://localhost:8080/openapi.json (after running `serve`) to see the autogenerated OpenAPI spec which Swagger uses.


## Autofilled Parameters
Any of the following parameter names or typehints will get autofilled with the corresponding request data:
```python
available_types = {
"request": Request, # full request object, contains all the other components
"query": Query, # query string
"body": Body, # request body bytes
"headers": Headers, # request headers dict[str, str]
"route": Route, # route string (without query string)
"full_path": FullPath, # full path string (with query string)
"method": Method, # request method str (GET, POST, etc.)
"file": File, # file bytes (essentially the same as body)
"client_addr": ClientAddr, # client ip address string (also contains host and port attributes)
}
```

### Decorators
```python
from socketwrench import route, methods, get, post, put, patch, delete, private
```
These decorators **do not modify** the functions they decorate, they simply `tag` the function by adding attributes to the functions.
```func.__dict__[key] = value```. This allows the setting function-specific preferences such as which methods to allow.
#### @tag
simply modifies the function's `__dict__` to add the specified attributes.
```python
@tag(do_not_serve=False, methods=["GET", "POST"], error_mode="traceback")
def my_function():
pass
```

The following decorators set the `available_methods` attribute of the function to the specified methods and tells the server to override its default behavior for the function.
* `@methods("GET", "POST", "DELETE")`: equivalent to `@tag(available_methods=["GET", "POST", "DELETE"])`
* `@get`, `@post`, `@put`, `@patch`, `@delete`, `@private`: self-explanatory

### Route Decorator
`@route("/a/{c}")` tells the server to use /a/{c} as the route for the function instead of using the function's name as it normally does. This also allows for capturing path parameters.
```python
@get
@post
@route("/a/{c}", error_mode="traceback")
def a(self, b, c=5):
print(f"calling a with {b=}, {c=}")
return f"captured {b=}, {c=}"
```

### Error Modes
* `"hide"` or `ErrorModes.HIDE`: returns `b"Internal Server Error"` in the response body when an error occurs.
* `type` or `ErrorModes.TYPE`: returns the error type only in the response body when an error occurs.
* `"short"` or `ErrorModes.SHORT`: returns the python error message but no traceback in the response body when an error occurs.
* `"traceback"` or `ErrorModes.TRACEBACK` or `ErrorModes.LONG` or `ErrorModes.TB`: returns the full traceback in the response body when an error occurs.

### favicon.ico
No need to use our favicon! pass a `str | Path` `.ico` filepath to `favicon` argument to use your own favicon. Alternatively, tag `@route('/favicon.ico')` on a function returning the path.

### fallback handler
Add a custom function to handle any requests that don't match any other routes.

# Planned Features
* [ ] Implement nesting / recursion to serve deeper routes and/or multiple classes
* [ ] Enforce OpenAPI spec with better error responses
* [ ] Serve static folders
* [ ] Make a better playground for testing endpoints
* [ ] Make a client-side python proxy object to make API requests from python
* [ ] Test on ESP32 and other microcontrollers
* [ ] Ideas? Let me know!

## Other Usage Modes
# Other Usage Modes
### Serve a module
Using commandline, just specify a filepath or file import path to a module.
```python
# my_module.py
def hello():
Expand All @@ -35,6 +110,7 @@ def hello():
```commandline
python -m socketwrench my_module
```
NOTE: this mode is experimental and less tested than the other modes.

### Serve a single function on all routes
```python
Expand Down
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 = "setuptools.build_meta"

[project]
name = "socketwrench"
version = "1.1.1"
version = "1.2.0"
description = "A simple Python library for creating web servers and APIs using sockets, supporting openapi and swagger."
readme = "README.md"
authors = [{ name = "Torin Halsted", email = "modularizer@gmail.com" }]
Expand Down
1 change: 1 addition & 0 deletions src/socketwrench/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Headers
)
from .tags import (
tag,
methods,
get,
post,
Expand Down

0 comments on commit 2a6f9b1

Please sign in to comment.