Hosting local servers easily, smooth as butter.
Project description
lynq
Lynq for Python is an open-source python framework that allows developers to host servers absurdly easily (we're talking 1-line easily) And this isn't even an exaggeration! Once you have Lynq imported, the world is basically in your hands.
Let's look at the most configurable and advanced way to host servers using Lynq, and move our way down the ladder to the easiest way.
ConfigurableLynqServer Class Documentation
The ConfigurableLynqServer class is an extension of the LynqServer class that adds flexibility and configurability to the basic HTTP server setup. This class allows the server to be configured either via a JSON configuration file, command-line arguments, or default values. Below is a detailed explanation of its functionality and components.
Overview
The ConfigurableLynqServer class is designed to provide a customizable HTTP server setup by allowing configuration through multiple sources:
- Configuration File: A JSON file containing server settings.
- Command-line Arguments: Options provided via the command line to override or set specific settings.
- Default Values: Fallbacks for when no other configuration is provided.
Class Definition
class ConfigurableLynqServer(LynqServer):
def __init__(self, config_file: Optional[str] = None, directory: Optional[str] = None, handler: Optional[Type[http.server.BaseHTTPRequestHandler]] = None):
config = self.load_config(config_file)
port = config.get("port", 8000) # Default to int
directory = directory or config.get("directory")
super().__init__(port, directory, handler)
@staticmethod
def load_config(config_file: Optional[str]) -> dict:
if config_file and Path(config_file).exists():
with open(config_file, 'r') as f:
try:
config = json.load(f)
logger.info(f"Loaded configuration from {config_file}")
return config
except json.JSONDecodeError as e:
logger.error(f"Error parsing config file: {e}")
else:
logger.warning(f"No valid config file found. Using default settings.")
return {}
@staticmethod
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Start a local HTTP server.")
parser.add_argument('--port', type=int, default=8000, help="Port number to run the server on")
parser.add_argument('--config', type=str, help="Path to configuration file")
parser.add_argument('--directory', type=str, help="Directory to serve files from")
return parser.parse_args()
Constructor: __init__
Parameters
-
config_file: An optional string representing the path to a JSON configuration file. If provided, this file is used to set the server's port and directory. -
directory: An optional string representing the directory from which files will be served. If not provided, it defaults to the directory specified in the configuration file or remainsNone. -
handler: An optional HTTP request handler class. If not specified, a default handler is used.
Functionality
-
Load Configuration: The constructor calls the
load_configmethod to load settings from the provided configuration file (if any). -
Port Setup: The server port is determined by checking the loaded configuration for a
"port"key. If absent, it defaults to8000. -
Directory Setup: The directory is set based on the provided argument or from the configuration file if the argument is
None. -
Superclass Initialization: The constructor calls the superclass (
LynqServer) constructor with the determined port, directory, and handler.
Methods
load_config(config_file: Optional[str]) -> dict
Description
This static method attempts to load a configuration file in JSON format.
Parameters
config_file: A string representing the path to the configuration file. It can beNoneif no file is provided.
Returns
- A dictionary containing the configuration settings. If the file doesn't exist or can't be parsed, an empty dictionary is returned.
Functionality
-
File Existence Check: The method checks if the provided configuration file path exists.
-
File Parsing: If the file exists, it attempts to parse it as JSON. Errors during parsing are logged, and an empty dictionary is returned.
-
Fallback: If the file doesn't exist or cannot be loaded, a warning is logged, and the method returns an empty dictionary.
parse_args() -> argparse.Namespace
Description
This static method parses command-line arguments to provide additional configuration options for the server.
Returns
- An
argparse.Namespaceobject containing the parsed arguments.
Arguments
-
--port: The port number on which the server should run. Defaults to8000. -
--config: The path to the configuration file. -
--directory: The directory to serve files from.
Usage
This method is typically called when running the server script from the command line, allowing users to override defaults or configuration file settings directly.
Usage Example
if __name__ == "__main__":
args = ConfigurableLynqServer.parse_args()
server = ConfigurableLynqServer(config_file=args.config, directory=args.directory)
server.serve_forever()
In this example:
- Command-line arguments are parsed.
- A
ConfigurableLynqServerinstance is created using the parsed arguments. - The server is started, serving files from the specified directory and listening on the specified port.
Summary
The ConfigurableLynqServer class offers a flexible way to configure and run an HTTP server. By leveraging configuration files, command-line arguments, and defaults, it provides a robust mechanism to tailor server behavior to various needs.
ConfigurableLynqServer is a great choice for experienced programmers that know what they're doing
LynqServer Class Documentation
The LynqServer class provides a basic, customizable HTTP server capable of serving files from a specified directory. It leverages Python’s http.server and socketserver modules to handle HTTP requests and manage the server’s lifecycle. Below is a detailed explanation of its functionality and components.
Overview
The LynqServer class is designed to facilitate the creation and management of a simple HTTP server. It provides functionality to:
- Initialize the server with a specific port and directory.
- Create a custom request handler.
- Start and stop the server.
- Automatically open a web browser pointing to the server’s URL.
Class Definition
class LynqServer:
def __init__(self, port: int, directory: Optional[str] = None, handler: Optional[Type[http.server.BaseHTTPRequestHandler]] = None):
self.port: int = port
self.directory: Path = Path(directory) if directory else Path.cwd()
self.handler: Type[http.server.BaseHTTPRequestHandler] = handler or self._create_handler()
try:
self.httpd: socketserver.TCPServer = socketserver.TCPServer(("localhost", self.port), self.handler)
self.httpd.directory = str(self.directory) # Set directory for the server
logger.info(f"Server initialized on port {self.port} with directory {self.directory}")
except OSError as e:
logger.error(f"Could not start server on port {self.port}: {e}")
raise
def _create_handler(self) -> Type[http.server.BaseHTTPRequestHandler]:
class CustomHandler(http.server.SimpleHTTPRequestHandler):
def translate_path(self, path: str) -> str:
# Removes query parameters, etc., from the URL path
path = path.split('?', 1)[0]
path = path.split('#', 1)[0]
path = Path(path).relative_to('/')
# Combine the requested path with the server's directory
full_path = self.server.directory / path
# Resolve the final absolute path
return str(full_path.resolve())
return CustomHandler
def _start_server(self) -> None:
server_thread: threading.Thread = threading.Thread(target=self.httpd.serve_forever)
server_thread.daemon = True
server_thread.start()
logger.info(f"Server started on port {self.port}")
def open(self) -> None:
self._start_server()
url = f"http://localhost:{self.port}"
logger.info(f"Opening browser at {url}")
webbrowser.open(url)
def _stop_server(self) -> None:
self.httpd.shutdown()
self.httpd.server_close()
logger.info(f"Server on port {self.port} stopped")
def close(self) -> None:
self._stop_server()
Constructor: __init__
Parameters
-
port: An integer specifying the port number on which the server will listen. -
directory: An optional string representing the directory from which the server will serve files. If not provided, it defaults to the current working directory (Path.cwd()). -
handler: An optional HTTP request handler class. If not specified, a custom handler is created using the_create_handlermethod.
Functionality
-
Port Initialization: The port is set based on the provided argument.
-
Directory Initialization: The directory is set to the provided path or defaults to the current working directory.
-
Request Handler: The server uses the provided handler or a custom handler created by
_create_handler. -
Server Setup: The server is initialized with the
socketserver.TCPServerclass, binding it tolocalhoston the specified port and using the configured request handler. -
Error Handling: If the server fails to start (e.g., due to the port being in use), an error is logged, and an
OSErroris raised.
Methods
_create_handler() -> Type[http.server.BaseHTTPRequestHandler]
Description
This private method creates and returns a custom request handler class based on http.server.SimpleHTTPRequestHandler.
Functionality
- Path Translation: The
translate_pathmethod is overridden to clean the URL path by removing query parameters and fragments. It then combines the cleaned path with the server’s base directory to determine the absolute file path to be served.
_start_server() -> None
Description
This private method starts the server in a background thread, allowing it to serve requests indefinitely without blocking the main thread.
Functionality
-
Threading: The server runs in a daemon thread, meaning it will automatically stop when the main program exits.
-
Logging: A message is logged when the server starts successfully.
open() -> None
Description
This method starts the server and opens the default web browser to the server's URL.
Functionality
-
Start Server: The server is started using
_start_server. -
Open Browser: The server's URL (
http://localhost:{port}) is opened in the default web browser.
_stop_server() -> None
Description
This private method stops the server gracefully by shutting it down and closing the server socket.
Functionality
-
Shutdown: The server's request-handling loop is stopped.
-
Close Socket: The server socket is closed, freeing up the port.
-
Logging: A message is logged indicating that the server has been stopped.
close() -> None
Description
This method is a public interface to stop the server by calling _stop_server.
Functionality
- Stop Server: The server is stopped and cleaned up.
Usage Example
if __name__ == "__main__":
server = LynqServer(port=8000, directory="/path/to/serve")
server.open()
# The server is now running and serving files
try:
while True:
pass # Keep the main thread alive
except KeyboardInterrupt:
server.close() # Stop the server on Ctrl+C
In this example:
- The server is initialized with a specific port and directory.
- The server is started, and the default web browser opens to the server's URL.
- The server runs indefinitely until interrupted (e.g., via
Ctrl+C), after which it stops gracefully.
Summary
The LynqServer class provides a simple and customizable way to create an HTTP server. With built-in methods for server management and a customizable request handler, it is well-suited for scenarios requiring a lightweight and configurable web server.
LynqServer is a great choice for intermediate programmers that know how this works, but aren't quite experienced enough to tackle ConfigurableLynqServer
launch Function Documentation
The launch function is a utility function that simplifies the process of starting a LynqServer instance. It is designed to quickly initialize, start, and manage the lifecycle of a basic HTTP server with minimal setup.
Function Definition
def launch(port: Optional[int] = None, directory: Optional[str] = None) -> None:
server: LynqServer = LynqServer(port or 8000, directory or ".")
try:
server.open()
input("\033[1;93mPress enter to exit your Lynq server...\n\033[0m")
finally:
server.close()
Parameters
-
port: An optional integer specifying the port number on which the server will listen. If not provided, the function defaults to port8000. -
directory: An optional string specifying the directory from which the server will serve files. If not provided, the function defaults to the current directory (".").
Functionality
-
Server Initialization:
- The function initializes a
LynqServerinstance using the providedportanddirectoryarguments. - If either argument is not provided, it falls back to the default values: port
8000and the current directory (".").
- The function initializes a
-
Server Startup:
- The
server.open()method is called to start the server. - This method also opens the default web browser to the server's URL (
http://localhost:{port}).
- The
-
User Prompt:
- The function waits for user input with a prompt: "Press enter to exit your Lynq server...".
- The prompt is displayed in yellow text to stand out in the console.
-
Server Shutdown:
- Regardless of how the function exits (either after user input or due to an exception), the server is properly closed by calling
server.close(). - This ensures that the server shuts down gracefully and the port is released.
- Regardless of how the function exits (either after user input or due to an exception), the server is properly closed by calling
Usage Example
if __name__ == "__main__":
launch(port=8080, directory="/path/to/serve")
In this example:
- The
launchfunction is called with a specific port (8080) and directory (/path/to/serve). - The server starts and serves files from the specified directory.
- The function waits for the user to press enter, after which the server shuts down.
Summary
The launch function provides a convenient way to start and manage a LynqServer instance with minimal code. It handles the server’s lifecycle, from initialization to shutdown, and includes user interaction to control when the server should stop running. This makes it an ideal entry point for scripts that need to quickly start a basic HTTP server.
launch() is a great choice for beginners, or basically anybody who just wants to open a server really quickly and efficiently.
Summary
As you saw from the above documentation, Lynq for Python is a quick, efficient web framework that is insanely easy to master, features many different levels of difficulty to appeal to different skill-levels of programmers, and overall is great at it's job; hosting local servers easily, as smooth as butter.
- All Lynq servers (no matter the type) will run until the heat death of the universe (unless you press enter to exit them manually)
Lynq x MSIE
You can now host custom instances of internet explorer that very easily allow you to remotely interact with them using their COM objects.
DISCLAIMER: We are not partnered with Microsoft or any other company, all material is open source.
InternetExplorerInstance Class Documentation
The InternetExplorerInstance class provides a high-level interface for controlling Internet Explorer instances via PowerShell commands. This class allows for launching a new Internet Explorer window, navigating to specific URLs, and refreshing the browser window. It utilizes the PowerShell COM object model to interact with Internet Explorer.
Overview
The InternetExplorerInstance class is designed to facilitate browser automation with Internet Explorer, using PowerShell scripts executed through Python’s subprocess module. This class is particularly useful for scripting and testing environments where Internet Explorer is required.
Class Definition
class InternetExplorerInstance:
def __init__(self) -> None:
self.pwie: Callable = lambda cmd: pwsh(f"$ie = New-Object -ComObject \"InternetExplorer.Application\"; {cmd}")
def open(self) -> None:
self.pwie("$ie.Visible = $true")
logger.info("Launched new internet explorer instance")
def navigate(self, link: Optional[str]) -> None:
self.pwie(f"$ie.Navigate({repr(link) or 'http://localhost'})")
logger.info(f"Navigated internet explorer into {link}")
def refresh(self) -> None:
self.pwie("$ie.Refresh()")
logger.info("Refresh internet explorer")
Methods
__init__() -> None
Description
The constructor initializes an instance of InternetExplorerInstance.
Functionality
- PowerShell Command Wrapper: Defines a
self.pwielambda function to run PowerShell commands that create a new Internet Explorer COM object. This lambda function calls thepwshfunction with the appropriate PowerShell command string.
open() -> None
Description
Launches a new Internet Explorer instance and makes it visible.
Functionality
-
PowerShell Command: Executes a PowerShell command to make the Internet Explorer instance visible.
-
Logging: Logs an informational message indicating that a new Internet Explorer instance has been launched.
navigate(link: Optional[str]) -> None
Description
Navigates the Internet Explorer instance to a specified URL.
Parameters
link: An optional string representing the URL to navigate to. IfNone, it defaults tohttp://localhost.
Functionality
-
PowerShell Command: Executes a PowerShell command to navigate to the specified URL.
-
Logging: Logs an informational message indicating the URL to which the browser is navigating.
refresh() -> None
Description
Refreshes the current page in the Internet Explorer instance.
Functionality
-
PowerShell Command: Executes a PowerShell command to refresh the current page.
-
Logging: Logs an informational message indicating that the Internet Explorer instance is being refreshed.
Dependencies
- PowerShell: Required to execute PowerShell commands.
- Internet Explorer: The class specifically targets Internet Explorer via its COM object model.
- Python Libraries:
subprocess.run: To execute PowerShell commands from Python.logging: To provide logging functionality.
Example Usage
if __name__ == "__main__":
ie = InternetExplorerInstance()
ie.open() # Launches a new Internet Explorer instance
ie.navigate("https://www.example.com") # Navigates to "https://www.example.com"
ie.refresh() # Refreshes the current page
In this example:
- An
InternetExplorerInstanceobject is created. - The
openmethod is called to launch a new Internet Explorer window. - The
navigatemethod is used to direct the browser to a specific URL. - The
refreshmethod is invoked to refresh the page.
Summary
The InternetExplorerInstance class provides a Python interface to automate Internet Explorer using PowerShell. It supports opening a new browser window, navigating to URLs, and refreshing the page. This class is useful in scenarios where Internet Explorer needs to be controlled programmatically, particularly in testing or automation tasks.
Microsoft Internet Explorer is deprecated, but it's still a handy tool to view local servers (via localhost), and Lynq let's you do that quickly and easily.
New features in Lynq for Python 2.0
P.E.B.L (Python Embedded Building Language) Documentation
P.E.B.L (Python Embedded Building Language) is a lightweight and flexible framework designed to facilitate the dynamic generation and serving of HTML content within a Python environment. It integrates seamlessly with the Lynq ecosystem, leveraging the power of LynqServer and ConfigurableLynqServer to deliver web content directly to the user.
Overview
P.E.B.L provides a streamlined interface for creating and managing web pages from within Python scripts. It supports a tag-based structure for building HTML components, enabling users to embed HTML directly in Python with ease. The core component of P.E.B.L is the PeblApp class, which manages the generation of HTML files and interacts with Lynq servers to serve this content.
Key Components
1. PeblApp Class
The PeblApp class is the heart of P.E.B.L. It manages the lifecycle of an HTML page, from creation to serving, within a LynqServer environment.
-
Initialization (
__init__):def __init__(self, name: str, server: LynqServer | ConfigurableLynqServer | None = None) -> None:
name: The name of the HTML file to be created (without the.htmlextension).server: An instance ofLynqServer,ConfigurableLynqServer, orNone. If provided, this server will be used to serve the generated HTML content.
Example:
app = PeblApp(name="index", server=my_server)
-
Tag Creation (
tag):def tag(self, type_: str, args: Optional[str] = None) -> Any:
type_: The type of HTML tag to be generated (e.g.,div,p,a).args: Optional attributes or content for the tag.
This method returns a
TagObjectwhich can be further manipulated or directly inserted into the HTML document.Example:
app.tag("div", "class='container'")
-
Single Line Insertion (
singular):def singular(self, ln: str) -> None:
ln: A string representing a single line of HTML to be appended to the HTML file.
This method allows for quick insertion of raw HTML content into the document.
Example:
app.singular("<h1>Welcome to P.E.B.L!</h1>")
-
Exiting Context (
__exit__):def __exit__(self, *_) -> None:
Automatically invoked when the
PeblAppinstance exits a context manager. This method ensures that the generated HTML content is passed to the server for serving.Example:
with PeblApp(name="index", server=my_server) as app: app.singular("<p>Hello, World!</p>")
-
Pass to Server (
pass_to_server):def pass_to_server(self) -> None:
This method handles passing the generated HTML file to the provided server instance and launching it. If no server is provided, an error is logged, and an exception is raised.
Example:
app.pass_to_server()
Usage Example
Here's a basic example of using P.E.B.L to generate and serve an HTML page:
from lynq.server import LynqServer
from lynq.pebl import PeblApp
# Create a LynqServer instance
server = LynqServer(port=8080, directory=".")
# Initialize the PeblApp with the server
with PeblApp(name="index", server=server) as app:
app.singular("<h1>Hello from P.E.B.L!</h1>")
app.singular("<p>This is a dynamically generated page.</p>")
Error Handling
-
If no server is provided when attempting to pass the script to a server, an error is logged, and an exception is raised.
Example Error:
logger.error("Cannot pass pebl script to server when no server was provided.")
-
The HTML file is automatically removed after it has been served to prevent unnecessary clutter, ensuring a clean working directory.
Integration with Lynq
P.E.B.L integrates tightly with Lynq, allowing for a fluid workflow where HTML content can be generated and served within the same Python environment. It leverages the existing LynqServer and ConfigurableLynqServer classes for this purpose.
This documentation covers the basics of working with P.E.B.L, including the main class PeblApp, its methods, and typical usage patterns. For more advanced features or extensions, refer to the full Lynq documentation or explore additional components within the lynq.pebl module.
Lynq 2.0 Logging with External Terminal Setup
Overview
Lynq 2.0 introduces an upgraded logging system that allows for more flexible and powerful logging configurations, including the ability to log to an external terminal or console. This enhancement provides developers with better control over logging output, making it easier to monitor and debug applications in real-time.
Key Features
- Enhanced Logging Flexibility: Configure logging to output to an external terminal, allowing real-time monitoring of log messages.
- Customizable Log Formats: Define custom formats for log messages to suit different needs and preferences.
- Advanced Logging Levels: Utilize different logging levels (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) for more granular control over what gets logged.
- Integration with External Terminal: Redirect log output to an external terminal for easier access and visibility.
Setup and Configuration
1. Initial Configuration
Lynq 2.0’s logging system can be configured using the logging module in Python. To set up logging to an external terminal, you need to configure the logging handlers appropriately.
2. Configure Logging to an External Terminal
To direct logs to an external terminal, follow these steps:
a. Import the Required Modules
import logging
import sys
b. Set Up the Logging Configuration
You can configure logging to output to an external terminal by using the StreamHandler provided by Python's logging module. This handler can be set up to write log messages to sys.stdout, which is the standard output stream often connected to the terminal.
def setuplogging():
# Create a logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # Set the root logger level
# Create a stream handler to output to the terminal
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG) # Set the handler level
# Create a formatter and set it for the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# Add the handler to the logger
logger.addHandler(handler)
c. Use the Logger in Your Application
After setting up logging, you can use the logger in your application code to log messages:
def main():
setuplogging()
logger = logging.getLogger(__name__)
logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
if __name__ == "__main__":
main()
3. Customizing Log Output
You can further customize the logging output by modifying the Formatter in the setuplogging function. For example, you can include additional information like module names or line numbers.
Example Formatter Customization
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(lineno)d - %(message)s')
4. Integration with External Terminal Applications
For enhanced integration, you might use external terminal applications or tools that support real-time log monitoring. Ensure that the terminal is set to receive logs from the standard output.
Example: Running a Script in a Terminal
Run your script in a terminal to see the log output directly:
python your_script.py
Troubleshooting
- No Logs Appearing: Ensure that the terminal or console you are using is configured correctly to display standard output.
- Incorrect Log Levels: Verify that the logging levels set in
setuploggingmatch the levels you are using in your code. - Formatting Issues: If log messages appear incorrectly formatted, check the
Formatterconfiguration in thesetuploggingfunction.
Summary
Lynq 2.0’s upgraded logging system provides a robust solution for directing log output to an external terminal, enhancing real-time monitoring and debugging capabilities. By configuring the StreamHandler to use sys.stdout, you can easily integrate logging into your terminal-based workflows and customize the logging output to meet your needs.
For more advanced configurations and additional features, refer to the Python logging documentation and explore Lynq's logging capabilities further.
Lynq Server Launch Documentation
Overview
Lynq provides functionality to launch servers with ease through the directlaunch and launch functions. These functions facilitate starting and stopping LynqServer or ConfigurableLynqServer instances, handling user interaction and server management in a streamlined manner.
Functions Overview
directlaunch
The directlaunch function sets up and starts a basic LynqServer instance, using default values if no specific configuration is provided.
Function Signature
def directlaunch(port: Optional[int] = None, directory: Optional[str] = None) -> None:
Parameters
port(Optional[int]): The port number on which the server will listen. Defaults to8000if not provided.directory(Optional[str]): The directory from which to serve files. Defaults to the current working directory (".") if not provided.
Functionality
- Initialization: Creates an instance of
LynqServerwith the specified port and directory. - Starting the Server: Calls the
openmethod to start the server. - User Interaction: Waits for user input to keep the server running. The prompt message is styled in yellow to indicate the user should press Enter to exit.
- Stopping the Server: Ensures the server is properly closed after exiting the user prompt.
Example Usage
# Launch a LynqServer on port 8080 serving from the current directory
directlaunch(port=8080)
launch
The launch function starts a server instance, which can be either a LynqServer or a ConfigurableLynqServer. It is more flexible than directlaunch as it accepts any server that adheres to the expected interface.
Function Signature
def launch(server: LynqServer | ConfigurableLynqServer):
Parameters
server(LynqServer | ConfigurableLynqServer): An instance ofLynqServerorConfigurableLynqServerthat will be started.
Functionality
- Starting the Server: Calls the
openmethod on the provided server instance to start it. - User Interaction: Waits for user input to keep the server running. The prompt message is styled in yellow to indicate the user should press Enter to exit.
- Stopping the Server: Ensures the server is properly closed after exiting the user prompt.
Example Usage
from lynq.server import LynqServer
from lynq.customserver import ConfigurableLynqServer
# Create a LynqServer instance
server = LynqServer(port=8080, directory=".")
# Launch the server
launch(server)
# Create a ConfigurableLynqServer instance with custom settings
config_server = ConfigurableLynqServer(config_file="config.json")
# Launch the configurable server
launch(config_server)
Error Handling
-
No Server Provided: Ensure that a valid
LynqServerorConfigurableLynqServerinstance is passed tolaunch. Otherwise, an exception may be raised. -
Port Conflicts: If the specified port is already in use, an
OSErroror similar exception may be encountered when trying to start the server. -
Directory Issues: Ensure the specified directory exists and is accessible. Incorrect paths may lead to errors when attempting to serve files.
Summary
The directlaunch and launch functions provide straightforward methods for starting and stopping Lynq servers. directlaunch is a simple wrapper around LynqServer, while launch offers flexibility by accepting any compatible server instance. Both functions ensure that the server runs interactively, waiting for user input to gracefully shut down.
The directlaunch function is a rename of the OG launch function, which has been repurposed to run already created servers with the same treatement as directlaunched ones
Hey! This is Elekk! I hope you enjoy this new release of Lynq for Python. As you may know, this is an entirely solo open-source project I've been working on. If you have Any_ issues, suggestions, or feedback, please open an issue!
New features in Lynq v3
- Bug fixes
- P.E.B.L has default supported tags; so instead of
app.tag("html", "arguments"), you can writeapp.html("arguments") - P.E.B.L apps are now created using the
appnodedecorator fromlynq.pebl.app - External logging has been changed to run in the terminal you started the server from.
- More logging
- Better clean up
- Many P.E.B.L improvements
- No more log file
- Warn count has been removed
- Other QoL changes
New features in Lynq v4
- Bug fixes
- Support for Basin config files
- Various improvements and updates to the README.md file
- Better launcher mechanics
- Basin now comes bundled in with the base release of Lynq v4.0.0 for Python and up
- Other QoL changes
- Improved app node
- Improved type annotations and types
- Global type for all LynqServer-like objects:
LynqServerOrRelatedObjectsfromlynq.lynqserverorrelated - The pizza is in the oven :>
New features in Lynq v5
Changelog
- MANY bug fixes
- Imports in backend files are now harder to get confused by
- Performance enhancements
- More Basin features
- BetterPebl 1 and 2 are fullt implemented
- Cool changes
- P.E.B.L and Basin apps are supercharged with new features and are now created using the
@app() .exportand@basinapp() .exportdecorators respectively.
lynqconfig
- You can now create a file in the same directory as the importing file(s) (the file(s) that are importing lynq) which will change some properties of how lynq works.
- Make sure to include ALL options or lynq will use defaults for everything. Any options you don't want to modify, just set them to None.
# lynqconfig.py
import logging
LOGGER = None
# This can be a logger object or 'None' for default logger.
LOGGINGCONFIG = {
"filename": "mylog.log"
}
# Additional arguments for the default logger. 'LOGGER' must be 'None' for this to take effect.
LOGGINGLEVEL = logging.DEBUG
# Modify the 'level' argument for the default logger. 'LOGGER' must be 'None' for this to take effect.
LOGGINGFORMAT = "%(asctime)s, %(levelname)s, %(message)s"
# Modify the 'format' argument for the default logger. 'LOGGER' must be 'None' for this to take effect.
CLEANPYCACHE = False
# This is a new feature in lynq v5. Lynq can now automatically remove all __pycache__ files in the lynq directory. This makes development much easier as it removes the need for manual deletion. Leaving this off might make lynq run slightly faster. Default is 'False'.
- More options will be added in the future.
- You can also clean pycache from lynq manually by running
python -m lynq._utils._lynq.manualcleanupin your command terminal.
_config
_config.pyis the backend file that manageslynqconfig.pyand the entire logging system. It is not importable*
*learn more at the 'what are _ prefixes' section.
_utils
_utilsis like the closet of useful stuff lynq uses to run how it does. It is not importable*
*learn more at the 'what are _ prefixes' section.
what are _ prefixes
- If something from lynq is prefixed with '_', this can be an item from a file (for ex. function or variable), it is not importable, which means you should not import them to your own projects. These items could potentially harm your computer if they aren't handled properly, and it's overall a bad idea and unintended to import them.
VERSION.md
Just a short markdown file indicating the current running lynq version and how to upgrade.
Where the heck is lynq/server.py???
- All server-related files (
server,customserverandbasinserver) have been moved to thelynq.serverpackage. lynq.serveris now located inlynq.server.standardlynq.customserveris now located inlynq.server.customlynq.basinserveris now located inlynq.server.basin
New features in Lynq v6
Changelog
- Lynq is A LOT more memory-efficient
- Less files for navigation
- All servers (
LynqServer,ConfigurableLynqServerandBasinLynqServer) are now all in one module:lynq.server appandbasinappcan now both be accessed in thelynq.appmodule
Complete reworking of PEBL apps
- PEBL apps have been reworked and are much more object oriented now.
Defining a PEBL app
# index.py
from lynq.app import app
from lynq.server import LynqServer
@app(LynqServer(
port=8000,
directory="./"
)) .export .standard
def my_pebl_app(self, name: str, age: int) -> None:
with self.head() as head:
... # Code here
with self.body() as body:
with body.p() as p:
p.singular("Your name is {}, you are {} years old.".format(name, age))
In the above example, we create an app called index.
DISCLAIMER: The name of the function/app DOES matter! It defines the name of your app, and therefore the HTML file assigned to it. It is recomended to use index for your main app. The name of the python file does not impact anything.
Now we have an app, but how do we pass it to it's server?
Spoiler: This has also been reworked
# main.py
from index import index
index(name="Bob", age=20) .launch()
How it works:
- The decorator
appandbasinappare classes, so passing the server or basin path respectively are actually passed toapp.__init__. Then,app.exportis a custom "Shallow Blank Slate Object" (SBSO) which is also a memory-efficient way to store small classes in memory. Afterexportis the "Export Method". Export methods change the way your PEBL app displays. The only export method implemented in Lynq PEBL so far isstandard. This implements elements normally, like everyone is used to. More export methods will be implemented later on. - In the
main.pyfile, theindexfunction is imported, but it's no longer a function because of the decorator. What we're calling.launch()on is actually aStandardAppExportObject; an object in charge of passing your apps to their dedicatedLynqServerin Lynq v6.
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lynq-6.tar.gz.
File metadata
- Download URL: lynq-6.tar.gz
- Upload date:
- Size: 50.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
693c3e77506556906b4b3b386471ede4fabea137502743ae57df60018f52d2dd
|
|
| MD5 |
27a46bf15a351a489328bdcfdfec456e
|
|
| BLAKE2b-256 |
b7c4e00cbc75e5801d0c06cd1f60df930394b941a76cf0802c423e9b26d18791
|
File details
Details for the file lynq-6-py3-none-any.whl.
File metadata
- Download URL: lynq-6-py3-none-any.whl
- Upload date:
- Size: 29.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b07d247bb7b80aa5ec9c06040fb57b7e28fe312d784c926a4b4eecf65989f747
|
|
| MD5 |
1d7987454cc3043a570163a8d22fe8e2
|
|
| BLAKE2b-256 |
6929630219df83de04e926f11837489ac3aa2eecc1e1146e6747c7c83fef08a2
|