A straightforward Python package that functions as an HTTP(s) server
Project description
CryskuraHTTP
CryskuraHTTP is a lightweight, customizable HTTP(s) server implemented in Python that supports basic HTTP(s) functionalities, including serving files and handling errors, with support for custom services, API calls, and authentication.
Features
CryskuraHTTP is an extension of Python's built-in http.server
, with minimal dependencies. You can leverage it to implement Python HTTP services without needing to install large software or libraries. It can also be used as a file sharing tool, supporting file serving and uploading through the browser, and can be launched from the Windows right-click menu.
- Customizable Services: Easily add custom services by extending the
BaseService
class. - Customizable API Calls: Define custom API calls with the
APIService
class. - Error Handling: Customizable error handling via the
ErrorService
class. - File Serving: Serve files from a specified directory via the
FileService
class. - File Uploading: Handle file uploads via POST requests with the
FileService
class. - WebPage Serving: Serve web pages without allowing directory listing via the
PageService
class. - Customizable Routes: Define custom routes for your services with the
Route
class. - Customizable Authentication: Implement custom authentication for your services.
- Auto uPnP Port Forwarding: Automatically forward ports using uPnP.
- Request Handling: Handle GET, POST, HEAD requests.
- Resumable Downloads: Supports resumable downloads for large files when serving files.
- Redirects: Supports 301 and 308 redirects.
- SSL Support: Optionally enable SSL by providing a certificate file.
- Threaded Server: Supports multi-threaded request handling for better performance.
- Command-Line Interface: Run the server from the command line with custom settings.
- Right Click Support: Supports right-click context menu for launching the server on Windows.
This project is not designed to replace full-scale, production-grade HTTP servers. Instead, it is ideal for small-scale web UI development or for use alongside tools like pywebview
and qtwebengine
. So don't expect it to handle thousands of concurrent connections or to have advanced features like load balancing or caching.
Requirements
- Python 3.x
psutil
library
Installation
-
Install the package using pip:
pip install cryskura
-
You can also download whl file from GitHub Releases and install it using pip:
pip install cryskura-1.0-py3-none-any.wh
-
Clone the repository and install manually if you want to modify the source code:
git clone https://github.com/HofNature/CryskuraHTTP.git cd CryskuraHTTP python setup.py install
Quick Start
Starting the Server
To start the server with default settings:
from cryskura import Server
server = HTTPServer(interface="127.0.0.1", port=8080)
server.start()
This will start the server on localhost
at port 8080
and serve files from the current directory.
Or you can run the server from the command line:
cryskura --interface 127.0.0.1 --port 8080 --path /path/to/serve
This will start the server on localhost
at port 8080
and serve files from /path/to/serve
.
Register to Right-Click Menu
You can add the server to the right-click context menu on Windows by running:
cryskura --addRightClick # You can also use -ar as a short form
Note: If arguments like
--interface
,--port
,--browser
, etc., are provided, the server will start with the specified settings when launched from the right-click menu.
If you want to remove it from the right-click menu, run:
cryskura --removeRightClick # You can also use -rr as a short form
Note: This feature is only available on Windows. For Windows 11 24h2 and above, if Sudo is enabled, it will be called automatically; otherwise, you need to run it manually with administrator privileges.
Stopping the Server
When using the Python API, you can stop the server by calling the stop()
method:
server.stop()
Note: Only the threaded server can be stopped using this method. The non-threaded server will block the thread, so it cannot be stopped by calling the
stop()
method. You can stop the non-threaded server by pressingCtrl+C
in the terminal.
When using the command line, you can stop the server by pressing Ctrl+C
in the terminal.
Command-Line Interface
You can get help on the command-line interface by running:
cryskura --help
This will show the available options:
-h, --help
: Show help message and exit.-u, --uPnP
: Enable uPnP port forwarding.-v, --version
: Show program's version number and exit.-b, --browser
: Open the browser after starting the server.-w, --webMode
: Enable web mode, which means only files can be accessed, not directories.-f, --forcePort
: Force to use the specified port even if it is already in use.-t, --allowUpload
: Allow file upload.-r, --allowResume
: Allow resume download.-ar, --addRightClick
: Add to right-click menu.-rr, --removeRightClick
: Remove from right-click menu.-d PATH, --path PATH
: The path to the directory to serve.-n NAME, --name NAME
: The name of the server.-p PORT, --port PORT
: The port to listen on.-c CERTFILE, --certfile CERTFILE
: The path to the certificate file.-i INTERFACE, --interface INTERFACE
: The interface to listen on.-j HTTP_TO_HTTPS, --http_to_https HTTP_TO_HTTPS
: Port to redirect HTTP requests to HTTPS.
Using as a Python Module
Custom Configuration
You can customize the server by providing different parameters:
from cryskura import Server
from cryskura.Services import FileService,PageService,RedirectService,APIService
# Create services
fs=FileService(r"/path/to/file","/Files",allowResume=True,allowUpload=True)
rs=RedirectService("/Redirect","https://www.google.com")
ps=PageService(r"/path/to/html","/")
# Define API function
def APIFunc(request, path, args, method):
print(f"API {method} {path} {args}")
request.send_response(200)
request.send_header("Content-Type", "text/plain")
request.end_headers()
request.wfile.write(b"API Call")
# Create API service
api=APIService("/API",func=APIFunc)
# Start the server
server=Server(services=[fs,rs,api,ps],certfile="/path/to/cert.pem",uPnP=True)
server.start()
This will start the server with the following services:
- FileService: Serves files from
/path/to/file
at the/Files
endpoint, allowing resumable downloads and file uploads. - RedirectService: Redirects requests from
/Redirect
tohttps://www.google.com
. - PageService: Serves web pages from
/path/to/html
at the root endpoint/
. - APIService: Handles API calls at the
/API
endpoint, printing request details and responding with a plain text message.
And with the following settings:
- SSL Support: Uses the certificate file located at
/path/to/cert.pem
for SSL encryption. - uPnP Port Forwarding: Automatically forwards ports using uPnP.
Route Priority
If multiple services have conflicting routes, the priority is determined by the order in which the services are listed in the services
parameter. The service listed first will have the highest priority, and so on.
For example:
from cryskura import Server
from cryskura.Services import FileService, PageService
fs = FileService(r"/path/to/files", "/files")
ps = PageService(r"/path/to/pages", "/")
server = Server(services=[fs,ps])
server.start()
In this case, FileService
will have priority over PageService
for routes that conflict between the two services. So if a request is made to /files/index.html
, it will be handled by FileService
and not PageService
.
Authentication
To implement custom authentication, you need to define an authentication function and pass it to the service that requires authentication. The authentication function should accept four parameters: cookies
, path
, args
, and operation
. It should return True
if the authentication is successful, and False
otherwise.
Here is an example of how to implement custom authentication:
from cryskura import Server
from cryskura.Services import FileService
# Define authentication function
def AUTHFunc(cookies, path, args, operation):
print(f"AUTH {operation} {path} {args}")
if args.get('passwd') == "passwd" and operation == "GET":
return True
elif args.get('passwd') == "admin" and operation == "POST":
return True
return False
# Create a file service with authentication
fs = FileService(r"/path/to/files", "/files", allowResume=True, auth_func=AUTHFunc)
# Start the server
server = Server(services=[fs])
server.start()
In this example, the AUTHFunc
function checks the passwd
parameter in the request arguments to authenticate GET and POST requests. If the passwd
parameter is passwd
for GET requests or admin
for POST requests, the authentication is successful. Otherwise, the authentication fails.
You can customize the AUTHFunc
function to implement your own authentication logic, such as checking cookies, headers, or other request parameters.
Custom Services
To create a custom service, extend the BaseService
class and implement the required methods:
from cryskura.Services import BaseService, Route
class MyService(BaseService):
def __init__(self):
routes = [Route("/myservice", ["GET"], "exact")]
super().__init__(routes)
def handle_GET(self, request, path, args):
request.send_response(200)
request.send_header("Content-Type", "text/plain")
request.end_headers()
request.wfile.write(b"Hello from MyService!")
Using the uPnP Client
CryskuraHTTP includes a built-in uPnP client to facilitate automatic port forwarding. This can be particularly useful when running the server behind a router or firewall.
Enabling uPnP
To enable uPnP port forwarding, you can use the --uPnP
flag when starting the server from the command line:
cryskura --interface 0.0.0.0 --port 8080 --path /path/to/serve --uPnP
Using uPnP in Python
You can also enable uPnP port forwarding when starting the server using the Python API:
from cryskura import Server
server = Server(interface="0.0.0.0", port=8080, uPnP=True)
server.start()
Custom uPnP Configuration
The built-in uPnP client can be used independently for custom port forwarding needs. Here’s how you can use the uPnPClient
class directly in your Python code:
Initializing the uPnP Client
First, you need to initialize the uPnPClient
with the desired network interface:
from cryskura import uPnP
# Initialize uPnP client for a specific interface
upnp_client = uPnP(interface="0.0.0.0")
# Use 0.0.0.0 for all IPv4 interfaces
if upnp_client.available:
print("uPnP client initialized successfully.")
else:
print("uPnP client is not available.")
Adding a Port Mapping
To add a port mapping, use the add_port_mapping
method:
if upnp_client.available:
success, mappings = upnp_client.add_port_mapping(
remote_port=8080,
local_port=8080,
protocol="TCP",
description="CryskuraHTTP Server"
)
if success:
print("Port mapping added successfully.")
for mapping in mappings:
print(f"Service is available at {mapping[0]}:{mapping[1]}")
else:
print("Failed to add port mapping.")
This will add a port mapping for port 8080
on the remote device to port 8080
on the local device using the TCP protocol. The description is just a label for the mapping, which can be used to identify it later.
Removing All Port Mappings
To remove port mappings, use the remove_port_mapping
method:
if upnp_client.available:
upnp_client.remove_port_mapping()
print("Port mapping removed.")
This will remove all port mappings that were added by the client. It's a good practice to remove port mappings when they are no longer needed. You can place this code in a cleanup section of your script or in an exception handler to ensure that the mappings are removed even if an error occurs. For example:
try:
Your code here...
except Exception as exception:
upnp_client.remove_port_mapping()
raise exception
This will ensure that the port mappings are removed even if an exception occurs during the execution of your code.
Troubleshooting uPnP
If you encounter issues with uPnP, ensure that:
-
Your router supports uPnP and has it enabled.
-
The
upnpclient
library is installed. You can install it using:pip install upnpclient
or install the
cryskura
package with theupnp
extra:pip install cryskura[upnp]
-
The network interface specified is correct and accessible.
For more detailed information on the uPnPClient
class and its methods, refer to the source code in the uPnP.py
file.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Contact
For any questions or suggestions, please open an issue here on GitHub.
Enjoy using CryskuraHTTP!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file cryskura-1.0b3.tar.gz
.
File metadata
- Download URL: cryskura-1.0b3.tar.gz
- Upload date:
- Size: 163.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 640b294fb5fa5c8cd6e9276b2937df262d337524f8023db07b4c2e1565f4cdcf |
|
MD5 | b7c6cc5d52271dcc23ba5378fd52d6dc |
|
BLAKE2b-256 | eb53fa738a4b3f8279016629440ca584016fd16802a16017250383e8c7946d22 |
File details
Details for the file cryskura-1.0b3-py3-none-any.whl
.
File metadata
- Download URL: cryskura-1.0b3-py3-none-any.whl
- Upload date:
- Size: 162.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2f43241fb583562add87d52f937be6b8d2fb6f113a4f7d9d2c78408e33bdcadb |
|
MD5 | 528d319100109a4c1ec22f486e58a111 |
|
BLAKE2b-256 | 4b05965af32a31cddb6b81b0a04efaa5f7db523e4e0ee26a643de912fc0bc628 |