Blah, Blah, Blah

  • My Introduction to Stable Diffusion

    For a few years now, I’ve been fascinated by programmatic art. For ten years or so, there’s been a stream of projects that do something along the lines of applying an artist-inspired filter (usually Van-Gogh) to existing photos to stylize them. Last year, the DALL-E project went a step further by generating images from textual descriptions and a library of images.

    I was stunned at both variations on existing images and images synthesized from descriptions. This summer, generative art got a little more accessible to the masses when Stable Diffusion was released, using similar technology, but publicly available models (at least for now).

    I think the business model leverages that you can make interesting images from the public models, but that most businesses will want to tune the image text-to-image models to suit their intended message. The models require an enormous amount of energy to train — the default one has an 11 metric-ton carbon footprint — and the model propagates cultural biases present in the underlying data. Both aspects seem significant enough to motivate an entrepreneur to hire out specialists.

    Stable Diffusion is a little tricky to install on a M1 Mac — you have to checkout a particular branch of stable-diffusion, currently `apple-silicon-mps-support`, and hope that nightly PyTorch builds are stable. You also have to register with HuggingFace to download an image model, which seem to be updated frequently at this point.

    There’s currently no GPU support for Apple silicon for Stable Diffusion, so you need to be patient, but here are some samples of the Stable Diffusion imagination…. that might sound a bit like “stable genius” and artistically sometimes the images resemble another product shoveled from a stable…. but again, samples of

  • Authentication in Rust with Rocket

    Rust Lesson #637, Authentication of REST Services goes something like this. Set up a Rocket REST service to require login authentication.

    There will be three sets of REST endpoints:

    • login which will read the user’s credentials from the request header and write a session key to a private cookie,
    • the endpoints you want to protect, which will just be your normal Rocket-style endpoint decorated with a new argument of type that implements rocket::request::FromRequest,
    • logout which will scrub authentication information from your cookies.

    Login

    The first time a user accesses your service, the user should be directed to use a login post which will expect a rocket::serde::json::Json<> structure containing any information you use to setup a session, like username and password, and a reference to a rocket::http::CookieJar to place a session key into.

    #[post("/users/login", format = "application/json", data = "<login_info>")]
    pub fn login(login_info: Json<LoginInfo>, cookies: &CookieJar<'_>) -> Option<String> {
    	....
    }
    

    Rocket uses reflection and annotation to perform magic on your route definition to ensure that in order to be well-formed, a request must provide values for the parameters. If a request doesn’t satisfy the parameters at face value, Rocket will respond with a 404.

    Inside your route definition, you can check login_info provided in the request header and consult your database or oracle to see if user should be able to authenticate.

    Upon success, you can write a session key to be used in subsequent requests. Typically, you’ll hash or encrypt a value readable only by the server to be used as a session key that would include fields like a user id, session id, and expiration time. Here all you have to do is write out a clear text string, for example JSON or whitespace separated values. Rocket’s cookie framework will encrypt the cookie value (but not the key) using the secret key in the Rocket.toml configuration.

    let token = "user638 1642533881115".to_string();
    let cookie = Cookie::build(AUTH_COOKIE, token).finish();
    cookies.add_private(cookie);
    

    Rocket also delivers the cookie back to the client.

    Session authentication

    This next part is the tricky one, since Rocket performs some sneaky dependency injection. When you register a route with a parameter implementing the FromRequest trait, Rocket will instantiate an implementation and invoke the from_request() method to determine if access to the route should be granted (Success), denied (Failure), or forwarded to another route (Forward).

    The parameter to from_request() is a Request instance that can provide the cookie provided during login. Parse the cookie’s value and determine whether access to the REST request should proceed.

    You might not need to touch the FromRequest instance in your route. It’s presence just signals the compiler to wire up authentication provided in your FromRequest::from_request() implementation to the route. You can attach other functionality to the FromRequest, such as information gleaned from authentication, like the username.

    Logout

    This is the easiest step. You’ll just set up a GET request whose only parameter is a rocket::http::CookieJar reference, from which you will remove your session-authentication cookie.

    static AUTH_COOKIE: &str = "auth";
    
    #[get("/users/logout")]
    pub fn logout(cookies: &CookieJar<'_>) -> Option<String> {
        cookies.remove_private(Cookie::named(AUTH_COOKIE));
        Some("OK".to_string())
    }
    

    Debugging notes

    Use curl to verify that the REST service authenticates before hacking away at your front end.

    Before starting this lesson, I was less-familiar with attaching a JSON header to the request and using cookies. Headers are easy, just use the --data and --header CLI options.

    curl --request POST --data '{"username":"some-user-name", "password": "clear-text-secret"}' --header "Content-Type: application/json" 192.168.1.9:7999/users/login -c -
    

    Cookies are a little tricker, but only because there’ll likely be a lot of gobbledy gook– you’ll be passing back encrypted values to the client. In the above example, the -c flag to curl signals to write cookies to a file. The output file - signifies to write to standard out, but you can write to a file for ensuring that the login session is active and later read the cookie file with the -b flag in another request.

    curl -v -b cookies.txt 192.168.1.9:7999/action/get/10/0
    

    You can even use both -b and -c with the same value and curl will update the cookies file.

    On versioning

    As with any software project, it doesn’t take too long to travel to versioning-hell. The notes above refer to my experience with Rocket 0.5.0-rc.1 using the secrets, tls, and json features. The features required serde 1.0.130, serde_json 1.0.67, and rocket_contrib 0.4.10 dependencies. rocket_cors is also useful if you want to separate your front-end from REST requests.

  • JavaScript and Logos

    There are two more doodles for the virtual refrigerator here, both leveraging my time with the Creative Coding course to experiment with the Minnesota Mandolin Orchestra logo that Ronda designed for the orchestra.

    Making a rubber stamp for the orchestra is a neglected item on my todo list and I’m not confident that the existing logo will make a good stamp. The text is small in comparison to the rest of the logo and I worry that the bulk of the logo will leave so much ink as to bleed through paper and will only be useful to stamp document margins, which can easily be trimmed and discarded.

    Below is the result of using the JavaScript Canvas API to wrap text letter by letter on an arc path. I decided to take a programmatic approach, rather than use a sketch app, to allow me to quickly update the text and image proportions and line weights.

    Thinking further about logos, I enrolled in another Domestika short course on logo design to better understand accepted aesthetics. The first assignment is to reimagine an existing logo. Since the MMO logo was already on my mind, I thought I’d take a stab at making its text more prominent and accentuating the mandolin shape. This time I used a mix of JavaScript and Inkscape sketches to allow me to quickly address and archive issues around font choice, size, and placement while giving me the freedom of incorporating SVG shapes that I drew by hand.

    I’m not sold on the combination of a decorative font that changes contrast, so perhaps a simpler and slightly larger font could be used. The logo might also benefit from using the same colors as the original.