Skip to content

Serve random meme (or any image) through Flask API and (optionally) store it in clipboard, to quickly paste it to your friends.

Notifications You must be signed in to change notification settings

knuurr/meme-api

Repository files navigation

meme-api 🐸

Serve random meme (or any image) through Flask API and store it in clipboard, to quickly paste it to your friends.

Usage

Project is to be used with Docker-compose.

I've created two docker-compose files, each allows different hosting scenario.

  • docker-compose-localhost.yml for hosting on localhost (With Docker Desktop, for example)
  • docker-compose-traefik.yml for hosting in homelab scenario. Comes with example, battle-tested Traefik configuration.

By default docker-compose expects docker-compose.yml file on root, so you can just rename one of files after adjustments and use:

docker-compose up -d

If you wish to use file with other name, or wish to not change file name, you need to specify -f option. Here's an example with docker-compose-localhost.yml:

docker-compose -f docker-compose-localhost.yml up -d

docker-compose-localhost.yml is enough to run this app on a local computer. Here I am running it via Docker Desktop and accessing endpoint via Postman:

But I am also presenting a more advanced deployment Scenario. docker-compose-traefik.yml shows how it is possible to deploy this app with:

So that it can be accesed more like a real-life API endpoint:

Together with this API, I also share simple AHK + Powershell script (tested on Windows 10) to easily fetch image from endpoint and copy it to clipboard for easy paste. All this is easily bindable to key combination, thanks to AHK.

Fetching script uses Windows toast notification, so that you can preview, how image you fetched looks like - or know if something went wrong

How to use

API

Container reads config.yaml to read configuration file. Based on exmaple file:

routes:
  - url: /cats
    method: GET
    image_dir: /images/cats
  - url: /dogs
    method: GET
    image_dir: /images/dogs

Here you should specify: endpoint for particular type of memes along with image folder path (as visible from inside container). This should correspond with docker-compose volume configuration on host:

volumes:
    - ./config.yaml:/config.yaml
    - "/path/to/folder1:/images/cats"
    - "/path/to/folder2:/images/dogs"

Script

If you wish to use script for automatic copy to clipboard, make sure you set up these parameters:

AHK

Inside AHK script, configure:

  • Powershell script path (needed for all the work, AHK just calls the script and handles bind)
  • keyboard bind
  • positional argument, this is needed for Powershell script to know which endpoint needs to be called. This allows to use single script for multiple endpoint.

Here is an example from repo. This AHK script

  • binds action to Ctrl+Alt+P (^!p::)
  • defines PS script path - here ir is relative to current directory (scriptPath)
  • runs PS script with cats positional argument
; Define the key bind (Ctrl+Alt+P)
^!p::
    ; Specify the path to the PowerShell script
    scriptPath := ".\fetch_image.ps1"
    
    ; Run the PowerShell script
    ; RunWait, powershell.exe -ExecutionPolicy Bypass -WindowStyle Minimized -File "%scriptPath% cats
    RunWait, powershell.exe -ExecutionPolicy Bypass -Command "%scriptPath% cats"
    
    ; Return to the AHK script
    return

Powershell script

Powershell does all the heavy job - it calls endpoint, fetches image, copies it to clipboard.

Positional argument is read from stdin, and, depending on it's value, a lookup for associated endpoint is done:

$endpoint = $args[0]

# Define the INI file data as a hashtable
$iniData = @{
    "dogs" = @{
        "URL" = "https://api.domain.local/meme/cats"
    }
    "cats" = @{
        "URL" = "http://localhost:5000/meme/dogs"
    }

In previous example, cats was passed, so http://localhost:5000/meme/dogs will be called.

If you wish to use headers, for example in authentication scenario, there is dedicated variable which can store your HTTP headers:

# Custom hearders for Invoke-WebRequest - like API key
$headers = @{
    'X-API-KEY' = 'your-api-key'
}

Depending on your needs, inside script, there are 3 possible Invoke-WebRequest configurations, each for slighly different scenario:

  • use of HTTP headers
  • withous use of HTTP headers
  • for use with self-signed certificates

Depending on your needs, you may need to comment the line with appropiate options and comment the other one.

### With headers
$response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers $headers

### Without any headers
# $response = Invoke-WebRequest -Uri $url -UseBasicParsing

# For PowerShell 6.0.0 > you can use "-SkipCertificateCheck" for self-signed certs
# $response = Invoke-WebRequest -SkipCertificateCheck -Uri $url -UseBasicParsing -Headers $headers

Self-signed certs

If you wish to fetch via script from location which is protected with self-siggned certificate, you have two options:

  • use -SkipCertificateCheck option (For PowerShell 6.0.0 >= only)
  • for older versions, uncomment below line inside script:
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

This will allow self-signed certificates to be used.

About

Serve random meme (or any image) through Flask API and (optionally) store it in clipboard, to quickly paste it to your friends.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published