### Run Channels Chat with Docker Source: https://hornbeam.dev/docs/examples/channels-chat Runs the Channels Chat example using Docker. Change into the example directory and start the services with docker-compose. ```bash cd examples/channels_chat docker-compose up ``` -------------------------------- ### Run Django with Hornbeam: create project, configure settings, start Source: https://hornbeam.dev/docs/guides/wsgi Steps to create a Django project, configure ALLOWED_HOSTS in settings.py, and start it with Hornbeam using the hornbeam:start function with pythonpath and workers options. ```shell django-admin startproject myproject cd myproject python manage.py migrate ``` ```python # myproject/settings.py ALLOWED_HOSTS = ['*'] # Configure appropriately for production ``` ```erlang hornbeam:start("myproject.wsgi:application", #{ pythonpath => [".", "myproject"], workers => 4 }). ``` -------------------------------- ### Run Channels Chat with Hornbeam CLI Source: https://hornbeam.dev/docs/examples/channels-chat Starts the Channels Chat example using the Hornbeam CLI. After running, open http://localhost:8000 in multiple browser windows to test the chat functionality. ```bash hornbeam run examples/channels_chat:app ``` -------------------------------- ### Project structure for channels_chat example Source: https://hornbeam.dev/docs/examples/channels-chat Shows the file layout of the channels_chat example project, listing the server, client, and deployment files. ```text examples/channels_chat/ ├── app.py # Channel handlers and ASGI app ├── index.html # Chat UI with Hornbeam JS client ├── Dockerfile # Container deployment └── docker-compose.yml ``` -------------------------------- ### node usage example Source: https://hornbeam.dev/docs/reference/python-api Example of getting the current node name. The comment shows the expected output. ```python from hornbeam_erlang import node current = node() # 'hornbeam@localhost' ``` -------------------------------- ### Start erlang_python application Source: https://hornbeam.dev/docs/erlang-python/getting-started Start the erlang_python application. The output shows that the application starts successfully, returning {ok, [erlang_python]}. ```erlang 1> application:ensure_all_started(erlang_python). {ok, [erlang_python]} ``` -------------------------------- ### Comparison output example Source: https://hornbeam.dev/docs/guides/benchmarking Example output from the comparison script showing performance differences between gunicorn and hornbeam. ```text ====================================================================== COMPARISON: GUNICORN vs HORNBEAM ====================================================================== Test Gunicorn (req/s) Hornbeam (req/s) Diff ---------------------------------------------------------------------- simple 1842.3 12543.2 +580.7% high_concurrency 1523.1 11892.3 +680.9% large_response 1234.5 8234.6 +567.2% ``` -------------------------------- ### Run Elixir example Source: https://hornbeam.dev/docs/erlang-python/getting-started Runs the complete Elixir example, which demonstrates basic calls, data conversion, callbacks, parallel processing (10x speedup), and AI integration. ```shell elixir --erl "-pa _build/default/lib/erlang_python/ebin" examples/elixir_example.exs ``` -------------------------------- ### Example benchmark output Source: https://hornbeam.dev/docs/erlang-python/asyncio Example output from the benchmark script showing timer throughput, callback dispatch, and I/O ready detection latency. ```text Timer throughput: 150,000 timers/sec Callback dispatch: 200,000 callbacks/sec I/O ready detection: <1ms latency ``` -------------------------------- ### Run Elixir AI example: elixir --erl -pa ... examples/elixir_example.exs Source: https://hornbeam.dev/docs/erlang-python/ai-integration Command to run the full Elixir AI example. Requires the erlang_python build and the example file. Demonstrates basic Python calls, data type conversion, registering Elixir callbacks, parallel processing (10x speedup), and semantic search. ```shell # Full Elixir example with AI integration elixir --erl "-pa _build/default/lib/erlang_python/ebin" examples/elixir_example.exs ``` -------------------------------- ### Backward compatible single-app start Source: https://hornbeam.dev/docs/guides/multi-app Shows two equivalent ways to start a single-app mode: the legacy direct form and the new mounts map with a root prefix. ```erlang %% These are equivalent: hornbeam:start("app:application", #{worker_class => wsgi}). hornbeam:start(#{ mounts => [{"/", "app:application", #{worker_class => wsgi}}] }). ``` -------------------------------- ### Benchmark a real Hornbeam app with hornbeam:start and wrk Source: https://hornbeam.dev/docs/guides/benchmarking Use to benchmark a real Hornbeam application instead of a Hello World example. Start the app with hornbeam:start/2, then run wrk against specific endpoints to measure realistic performance. The wrk flags -t4 -c100 -d30s specify 4 threads, 100 connections, and a 30-second duration. ```shell # Start your app hornbeam:start("myapp:app", #{...}). # Benchmark specific endpoints wrk -t4 -c100 -d30s http://localhost:8000/api/users wrk -t4 -c100 -d30s http://localhost:8000/api/search?q=test ``` -------------------------------- ### Install wrk benchmarking tool Source: https://hornbeam.dev/docs/guides/benchmarking Install the wrk benchmarking tool on macOS or Linux. On Debian-based systems, apache2-utils provides the ab tool as an alternative. ```bash # macOS brew install wrk # Linux (Ubuntu/Debian) apt-get install wrk # or apt-get install apache2-utils # for ab ``` -------------------------------- ### Start Hornbeam using environment variables Source: https://hornbeam.dev/docs/reference/configuration Starts Hornbeam by reading configuration from environment variables with defaults. Demonstrates using bind and workers from environment. ```erlang %% Read from environment hornbeam:start("app:application", #{ bind => os:getenv("HORNBEAM_BIND", "127.0.0.1:8000"), workers => list_to_integer(os:getenv("HORNBEAM_WORKERS", "4")) }). ``` -------------------------------- ### Start channel application from Erlang Source: https://hornbeam.dev/docs/guides/channels Programmatic startup of the application using the hornbeam:start function. ```erlang hornbeam:start("your_module:app", #{ worker_class => asgi, channel_modules => ["your_module"] }). ``` -------------------------------- ### publish usage example Source: https://hornbeam.dev/docs/reference/python-api Example of publishing a message and printing the number of notified subscribers. ```python from hornbeam_erlang import publish # Notify all subscribers count = publish('notifications', { 'type': 'alert', 'message': 'Server restart in 5 minutes' }) print(f"Notified {count} subscribers") ``` -------------------------------- ### state_get_multi usage example Source: https://hornbeam.dev/docs/reference/python-api Example of fetching multiple keys at once. The comment shows the expected result, including a None for a missing key. ```python from hornbeam_erlang import state_get_multi users = state_get_multi(['user:1', 'user:2', 'user:3']) # {'user:1': {...}, 'user:2': {...}, 'user:3': None} ``` -------------------------------- ### nodes usage example Source: https://hornbeam.dev/docs/reference/python-api Example of retrieving connected nodes. The comment shows a sample list. ```python from hornbeam_erlang import nodes connected = nodes() # ['worker1@server', 'worker2@server', 'gpu@ml-server'] ``` -------------------------------- ### Start Hornbeam with FastAPI app Source: https://hornbeam.dev/docs/getting-started Starts Hornbeam with the FastAPI ASGI application. ```erlang hornbeam:start("app:app", #{worker_class => asgi}). ``` -------------------------------- ### Hornbeam Quick Start: Multiple Applications Source: https://hornbeam.dev/docs/reference/configuration Starts Hornbeam with multiple mounted applications. The first mount serves an ASGI app at the root, and the second serves a WSGI app at the /api prefix. ```erlang hornbeam:start(#{ mounts => [ {"/", "frontend:app", #{worker_class => asgi}}, {"/api", "api:app", #{worker_class => wsgi}} ], bind => "0.0.0.0:8000" }). ``` -------------------------------- ### Example benchmark output Source: https://hornbeam.dev/docs/guides/benchmarking Example output from the quick benchmark script on an Apple M4 Pro with Python 3.13, OTP 28, and February 2026. Shows throughput, latency, and failed request counts for the three scenarios. ```text === Benchmark: Simple requests (10000 requests, 100 concurrent) === Requests per second: 66000.00 [#/sec] (mean) Time per request: 1.52 [ms] (mean) Failed requests: 0 === Benchmark: High concurrency (5000 requests, 500 concurrent) === Requests per second: 71000.00 [#/sec] (mean) Time per request: 7.04 [ms] (mean) Failed requests: 0 === Benchmark: Large response (1000 requests, 50 concurrent) === Requests per second: 58000.00 [#/sec] (mean) Time per request: 0.86 [ms] (mean) Failed requests: 0 ``` -------------------------------- ### state_keys usage example Source: https://hornbeam.dev/docs/reference/python-api Example of retrieving keys with a prefix filter. The comment shows the expected list of keys. ```python from hornbeam_erlang import state_keys # Get all user keys user_keys = state_keys('user:') # ['user:1', 'user:2', 'user:123'] ``` -------------------------------- ### Run reentrant demo with rebar3 shell Source: https://hornbeam.dev/docs/erlang-python/scalability Commands to run the reentrant callback demo. Start a `rebar3 shell`, then call `reentrant_demo:start()` and `reentrant_demo:demo_all()` to execute the complete demonstration. ```shell # Run the demo rebar3 shell 1> reentrant_demo:start(). 2> reentrant_demo:demo_all(). ``` -------------------------------- ### Start web server and connect to GPU nodes with Hornbeam Source: https://hornbeam.dev/docs/examples/distributed-ml Starts the web server Erlang node, pings the two GPU worker nodes to establish connections, and starts Hornbeam with the ASGI worker class and the distributed_ml Python path. ```erlang # On web-server erl -name web@web-server -setcookie mysecret # Connect to GPU nodes net_adm:ping('worker1@gpu-server-1'). net_adm:ping('worker2@gpu-server-2'). # Start Hornbeam hornbeam:start("app:app", #{ worker_class => asgi, pythonpath => ["distributed_ml"] }). ``` -------------------------------- ### Hornbeam Quick Start: Single Application Source: https://hornbeam.dev/docs/reference/configuration Starts a single Hornbeam application with the ASGI worker class. The bind address is set to 0.0.0.0:8000 and four workers are used. ```erlang hornbeam:start("myapp:application", #{ bind => "0.0.0.0:8000", workers => 4, worker_class => asgi }). ``` -------------------------------- ### Install free-threaded Python Source: https://hornbeam.dev/docs/erlang-python/scalability Install a free-threaded Python 3.13+ build using Homebrew, building from source, or pyenv. ```shell # macOS with Homebrew brew install python@3.13 --with-freethreading # Or build from source ./configure --disable-gil make && make install # Or use pyenv PYTHON_CONFIGURE_OPTS="--disable-gil" pyenv install 3.13.0 ``` -------------------------------- ### Verify Build with application:ensure_all_started and py:eval Source: https://hornbeam.dev/docs/erlang-python/scalability Verifies the build by starting the erlang_python application and running a basic py:eval call. Expected output shows successful start and evaluation result. ```erlang %% Check that the NIF loaded successfully 1> application:ensure_all_started(erlang_python). {ok, [erlang_python]} %% Run basic verification 2> py:eval("1 + 1"). {ok, 2} ``` -------------------------------- ### Hornbeam WSGI Configuration Example Source: https://hornbeam.dev/docs/guides/wsgi Example configuration for starting a WSGI application with Hornbeam. Sets worker class to wsgi, 4 workers, 30-second timeout, 1000 max requests, keep-alive of 2 seconds, and Python path including '.' and 'src'. ```erlang hornbeam:start("app:application", #{ %% Protocol worker_class => wsgi, %% Workers workers => 4, % Number of Python workers timeout => 30000, % Request timeout (ms) max_requests => 1000, % Recycle workers after N requests %% HTTP keepalive => 2, % Keep-alive timeout (seconds) %% Python pythonpath => [".", "src"] }). ``` -------------------------------- ### Configure node via vm.args Source: https://hornbeam.dev/docs/guides/distributed-rpc Example vm.args file to configure a node with name, cookie, and Erlang flags (+K true, +A 128). ```erlang ## vm.args -name hornbeam@192.168.1.10 -setcookie mysecret +K true +A 128 ``` -------------------------------- ### FastAPI/Starlette integration with erlang.async_call() Source: https://hornbeam.dev/docs/erlang-python/threading Demonstrates using erlang.async_call() in FastAPI endpoints and WebSocket handlers. The example includes a GET endpoint and a WebSocket endpoint, both using async_call for asyncio compatibility. ```python from fastapi import FastAPI import erlang app = FastAPI() @app.get("/user/{user_id}") async def get_user(user_id: int): # Use async_call for asyncio compatibility user = await erlang.async_call('get_user', user_id) return {"user": user} @app.websocket("/ws") async def websocket_endpoint(websocket): await websocket.accept() while True: data = await websocket.receive_text() # Safe to use in WebSocket handlers result = await erlang.async_call('process_message', data) await websocket.send_text(result) ``` -------------------------------- ### Execute an action asynchronously with execute_async() and await_result() Source: https://hornbeam.dev/docs/reference/python-api Use execute_async() to start an async task and await_result() to wait for its result. execute_async() returns a task ID (binary string). await_result() accepts a timeout in milliseconds (default 30000) and raises RuntimeError if the task fails or times out. The example starts a training task and waits for the result. ```python from hornbeam_erlang import execute_async, await_result # Start async task task_id = execute_async('ml', 'train', dataset) # Do other work... # Wait for result result = await_result(task_id, timeout_ms=60000) ``` -------------------------------- ### Stream results from a hook action with stream() Source: https://hornbeam.dev/docs/reference/python-api Use stream() to get a generator yielding chunks from a hook action. The example streams an LLM response and prints each chunk without newlines. ```python from hornbeam_erlang import stream # Stream LLM response for chunk in stream('llm', 'generate', prompt): print(chunk, end='', flush=True) ``` -------------------------------- ### Using the semantic search module Source: https://hornbeam.dev/docs/erlang-python/ai-integration Erlang shell session demonstrating how to initialize the model, index documents, and search with a query, showing example output. ```erlang 1> semantic_search:init_embedding_model(). ok 2> Docs = [ <<"Erlang is great for building distributed systems">>, <<"Python excels at machine learning">>, <<"The BEAM VM provides fault tolerance">>, <<"Neural networks require GPU acceleration">> ]. 3> Index = semantic_search:index(Docs). 4> semantic_search:search(<<"concurrent programming">>, Index). [{<<"Erlang is great for building distributed systems">>, 0.42}, {<<"The BEAM VM provides fault tolerance">>, 0.38}, ...] ``` -------------------------------- ### Real-world Performance Results (Text) Source: https://hornbeam.dev/docs/erlang-python/ai-integration Output from the example showing sequential vs parallel timing and speedup. ```text Sequential (10 items × 100ms): 1.01 seconds Parallel (10 Erlang processes): 0.10 seconds Speedup: 10x faster! ``` -------------------------------- ### Get pool statistics with py_pool:get_stats() Source: https://hornbeam.dev/docs/erlang-python/context-affinity Retrieves the current pool statistics, including the number of workers, available workers, checked-out workers, and pending requests. The example uses pattern matching to assert the expected values. ```erlang Stats = py_pool:get_stats(), #{ num_workers := 8, available_workers := 6, %% 2 workers are checked out checked_out := 2, pending_requests := 0 } = Stats. ``` -------------------------------- ### Common Test suite for Erlang app with hackney Source: https://hornbeam.dev/docs/guides/erlang-apps Common Test suite for an Erlang application using the hackney HTTP client. Starts the application and hackney in init_per_suite, stops them in end_per_suite, and verifies a GET request to localhost:8000 returns a binary body. ```erlang %% test/my_app_SUITE.erl -module(my_app_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0, init_per_suite/1, end_per_suite/1]). -export([test_api/1]). all() -> [test_api]. init_per_suite(Config) -> {ok, _} = application:ensure_all_started(hackney), {ok, _} = application:ensure_all_started(my_app), Config. end_per_suite(_Config) -> application:stop(my_app), application:stop(hackney), ok. test_api(_Config) -> {ok, 200, _Headers, ClientRef} = hackney:request(get, <<"http://localhost:8000/">>, [], <<>>, []), {ok, Body} = hackney:body(ClientRef), true = is_binary(Body), ok. ``` -------------------------------- ### Call a registered Erlang function synchronously with call() Source: https://hornbeam.dev/docs/reference/python-api Use call() to invoke a registered Erlang function and get its result. The function name must be registered via hornbeam:register_function/2. The example shows calling 'add' with two integers and validating a token. ```python from hornbeam_erlang import call # Call registered function result = call('add', 1, 2) # Returns 3 # Validate token user_id = call('validate_token', token) ``` -------------------------------- ### Run Channels Chat from Erlang Shell Source: https://hornbeam.dev/docs/examples/channels-chat Starts the Channels Chat example from an Erlang shell. First launch rebar3 shell, then call hornbeam:start/2 with the app path and configuration map specifying the ASGI worker class, Python path, and worker count. ```erlang rebar3 shell hornbeam:start("examples.channels_chat.app:app", #{ worker_class => asgi, pythonpath => ["examples/channels_chat"], workers => 4 }). ``` -------------------------------- ### Project structure for chat_demo Source: https://hornbeam.dev/docs/examples/websocket-chat Shows the file layout for the WebSocket chat example: app.py holds the ASGI application, static/index.html is the chat UI, and requirements.txt lists dependencies. ```text chat_demo/ ├── app.py # ASGI application ├── static/ │ └── index.html # Chat UI └── requirements.txt ``` -------------------------------- ### Start Hornbeam with WSGI app Source: https://hornbeam.dev/docs/getting-started Starts the Erlang shell and then starts Hornbeam with the WSGI application. ```erlang %% Start the shell rebar3 shell %% Start hornbeam with your app hornbeam:start("myapp:application"). ``` -------------------------------- ### Initialize and Configure Logging Source: https://hornbeam.dev/docs/erlang-python/logging Starts the erlang-python application and sets the logging level to info. ```erlang %% Basic usage {ok, _} = application:ensure_all_started(erlang_python). %% Logging ok = py:configure_logging(#{level => info}). {ok, _} = py:eval(<<"import logging; logging.info('hello')">>). ``` -------------------------------- ### cache_stats usage example Source: https://hornbeam.dev/docs/reference/python-api Example usage of cache_stats. Retrieves cache statistics and prints the hit rate as a percentage. The comment shows an example output dictionary. ```python from hornbeam_ml import cache_stats stats = cache_stats() # {'hits': 150, 'misses': 23, 'hit_rate': 0.867} print(f"Cache hit rate: {stats['hit_rate']:.1%}") ``` -------------------------------- ### TCP server with create_server Source: https://hornbeam.dev/docs/erlang-python/asyncio Shows how to create a TCP server using create_server() with a custom protocol class. The example defines an EchoServerProtocol that echoes received data back to the client. ```python import asyncio class EchoServerProtocol(asyncio.Protocol): def connection_made(self, transport): peername = transport.get_extra_info('peername') print(f'Connection from {peername}') self.transport = transport def data_received(self, data): message = data.decode() print(f'Received: {message}') # Echo back self.transport.write(data) def connection_lost(self, exc): print('Connection closed') async def main(): loop = asyncio.get_running_loop() server = await loop.create_server( EchoServerProtocol, host='127.0.0.1', port=8888, reuse_address=True ) async with server: await server.serve_forever() ``` -------------------------------- ### Start GPU worker node with erl and ensure erlang_python Source: https://hornbeam.dev/docs/examples/distributed-ml Starts an Erlang node named worker1 on gpu-server-1 with the shared cookie 'mysecret', then ensures the erlang_python application is started in the shell. ```erlang # On gpu-server-1 erl -name worker1@gpu-server-1 -setcookie mysecret # In the shell application:ensure_all_started(erlang_python). ``` -------------------------------- ### Python API: ErlangHandler and setup_logging Source: https://hornbeam.dev/docs/erlang-python/logging After py:configure_logging(), these functions are available on the erlang module. Shows how to add the ErlangHandler to the root logger or use the setup helper with level and format options. ```python import erlang # ErlangHandler - logging.Handler subclass handler = erlang.ErlangHandler() logging.getLogger().addHandler(handler) # Or use the setup helper erlang.setup_logging(level=20) # INFO level erlang.setup_logging(level=10, format='%(name)s: %(message)s') ``` -------------------------------- ### Start Hornbeam with Flask app Source: https://hornbeam.dev/docs/getting-started Starts Hornbeam with the Flask WSGI application. ```erlang hornbeam:start("app:application"). ``` -------------------------------- ### state_delete usage example Source: https://hornbeam.dev/docs/reference/python-api Example of removing a key from ETS shared state. ```python from hornbeam_erlang import state_delete state_delete('user:123') ``` -------------------------------- ### Configure Global Options with hornbeam:start Source: https://hornbeam.dev/docs/guides/multi-app Shows how to set global options for all mounts, including bind address, Python path, virtual environment, SSL certificates, and an HTTP hook that logs each request. ```erlang hornbeam:start(#{ mounts => [ {"/api", "api:app", #{worker_class => asgi}}, {"/", "frontend:app", #{worker_class => wsgi}} ], %% Global options bind => "0.0.0.0:8000", pythonpath => [".", "apps"], venv => "/path/to/venv", ssl => true, certfile => "/path/to/cert.pem", keyfile => "/path/to/key.pem", %% HTTP hooks apply to all mounts hooks => #{ on_request => fun(Req) -> logger:info("~s ~s", [maps:get(method, Req), maps:get(path, Req)]), Req end } }). ``` -------------------------------- ### state_set usage example Source: https://hornbeam.dev/docs/reference/python-api Example of storing a user dictionary in ETS shared state. ```python from hornbeam_erlang import state_set state_set('user:123', {'name': 'Alice', 'email': 'alice@example.com'}) ``` -------------------------------- ### Run Python benchmark script Source: https://hornbeam.dev/docs/guides/benchmarking Shows how to run the benchmark script with options for WSGI, ASGI, custom bind address, and saving results to JSON. ```bash # WSGI benchmarks python benchmarks/run_benchmark.py # ASGI benchmarks python benchmarks/run_benchmark.py --asgi # Custom bind address python benchmarks/run_benchmark.py --bind 0.0.0.0:9000 # Save results to JSON python benchmarks/run_benchmark.py --output results.json ``` -------------------------------- ### Start Hornbeam with Django app Source: https://hornbeam.dev/docs/getting-started Starts Hornbeam with the Django WSGI application, setting the pythonpath. ```erlang hornbeam:start("myproject.wsgi:application", #{ pythonpath => [".", "myproject"] }). ``` -------------------------------- ### Start Hornbeam with ASGI app Source: https://hornbeam.dev/docs/getting-started Starts Hornbeam with the ASGI application, specifying the worker_class as asgi. ```erlang hornbeam:start("myapp:application", #{worker_class => asgi}). ``` -------------------------------- ### Run event loop benchmarks Source: https://hornbeam.dev/docs/erlang-python/asyncio Run the event loop benchmarks to measure performance. Example output shows timer throughput, callback dispatch, and I/O ready detection latency. ```bash python3 examples/benchmark_event_loop.py ``` -------------------------------- ### rpc_call usage example Source: https://hornbeam.dev/docs/reference/python-api Example of calling a remote function on a GPU node with a 30-second timeout. ```python from hornbeam_erlang import rpc_call # Call ML model on GPU node result = rpc_call( 'worker@gpu-server', 'ml_model', 'predict', [input_data], timeout_ms=30000 ) ``` -------------------------------- ### TCP client with create_connection Source: https://hornbeam.dev/docs/erlang-python/asyncio Shows how to establish a TCP client connection using create_connection() with a custom protocol class. The example defines an EchoClientProtocol that sends a message and waits for the connection to be lost. ```python import asyncio class EchoClientProtocol(asyncio.Protocol): def __init__(self, message, on_con_lost): self.message = message self.on_con_lost = on_con_lost def connection_made(self, transport): transport.write(self.message.encode()) def data_received(self, data): print(f'Received: {data.decode()}') def connection_lost(self, exc): self.on_con_lost.set_result(True) async def main(): loop = asyncio.get_running_loop() on_con_lost = loop.create_future() transport, protocol = await loop.create_connection( lambda: EchoClientProtocol('Hello, World!', on_con_lost), host='127.0.0.1', port=8888 ) try: await on_con_lost finally: transport.close() ``` -------------------------------- ### state_decr usage example Source: https://hornbeam.dev/docs/reference/python-api Example of decrementing a counter and raising an exception when the remaining value goes below zero. ```python from hornbeam_erlang import state_decr remaining = state_decr('quota:user:123') if remaining < 0: raise QuotaExceeded() ``` -------------------------------- ### Production Release: Build and run with rebar3 Source: https://hornbeam.dev/docs/guides/erlang-apps Build a production release with rebar3 as prod release, then run it in foreground or as a daemon with stop command. ```bash # Build release rebar3 as prod release # Run _build/prod/rel/my_app/bin/my_app foreground # Or as daemon _build/prod/rel/my_app/bin/my_app daemon _build/prod/rel/my_app/bin/my_app stop ``` -------------------------------- ### Start Hornbeam with custom Cowboy routes Source: https://hornbeam.dev/docs/guides/custom-apps Configure Hornbeam to start with custom Cowboy routes, including health, metrics, and WebSocket handlers. The routes are defined in the Erlang start call, with each route mapping a path to a handler module. ```erlang %% Start with custom routes hornbeam:start("app:app", #{ worker_class => asgi, pythonpath => ["priv/python"], routes => [ %% Health check - pure Erlang, no Python {"/health", health_handler, []}, %% Metrics endpoint {"/metrics", metrics_handler, []}, %% WebSocket with custom handler {"/ws/[...]", my_websocket_handler, []} ] }). ``` -------------------------------- ### Create a Python virtual environment with AI dependencies Source: https://hornbeam.dev/docs/erlang-python/ai-integration Commands to create and activate a Python virtual environment and install common AI libraries: sentence-transformers, numpy, openai, and anthropic. ```bash # Create venv with AI dependencies python3 -m venv ai_venv source ai_venv/bin/activate # Install common AI libraries pip install sentence-transformers numpy openai anthropic ``` -------------------------------- ### Starting an ASGI application with lifespan Source: https://hornbeam.dev/docs/guides/asgi Configures the Hornbeam start command to enable lifespan events for an ASGI application. ```erlang hornbeam:start("app:app", #{ worker_class => asgi, lifespan => on % Required for lifespan events }). ```