Avatar

rozek

Physicist, Senior Developer and IT Consultant, University Lecturer, Freelancer and Startup Founder
Joined October 5, 2024
Public vals
57
rozek avatar
rozek
Hello_World
HTTP
(just a simple experiment with Val.Town)
0
rozek avatar
rozek
OpenRouter_Test
HTTP
This is a simple test of OpenRouter and their new offering of DeepSeek-R1 671B for free The actual wrapper for the request is found in val OpenRouterChatCompletion with a simple smoke test in val OpenRouterChatCompletion_Test Please mind that the OpenRouter server often takes a long time to respond - and even then, it often does not respond with an actual chat completion but with an error message. Current overall usage limits for this instance of the app are: up to 20 requests/minute and up to 200 requests/day.
0
rozek avatar
rozek
OpenRouterChatCompletionLead
HTTP
how long until "OpenAIChatCompletion" becomes available again?
0
rozek avatar
rozek
OpenRouterChatCompletion_Test
HTTP
a simple smoke test for val "OpenRouterChatCompletion"
0
rozek avatar
rozek
OpenRouterChatCompletion
HTTP
free, but rate-limited access to the OpenRouter API
0
rozek avatar
rozek
OpenAIChatCompletion
HTTP
Use Val.Town's Open AI access wherever you need to enter AI Provider Credentials Perhaps, you are going to build an AI application for the public with Val.Town. Personally, you may want to use the Open AI access that comes with Val.Town, but for the entirety of your users the rate limits of that access will be too low. Thus, you may want them to bring their own AI provider with their own server URL and access key. But, wait, how do you than use your own application, still using Val.Town's Open AI access? This is where this val comes in (assuming that you already have a Val.Town account, either a free or a paid one): fork this val use the fork's HTTP endpoint URL (in the form "https://XXX-openaichatcompletion.web.val.run") as AI server URL define an environment variable called "OpenAIChatCompletion" with any kind of content (but without any blanks or control characters, e.g., a UUID ) and use that as your personal access key Now, you can ask everybody to provide their AI credentials and still use the OpenAI access provided by Val.Town for your personal tests. Nota bene: if the environment variable "OpenAIChatCompletion" has not been defined, access to your fork's endpoint is free for everybody! In addition to the described authorization, this val also provides resource "throttling" (using val floatingQuotaTracker in sqlite tables "OpenAIChatCompletion_Info" and "OpenAIChatCompletion_Log") and calculates some access statistics (using val InvocationTracker in sqlite tables "OpenAIChatCompletion_Usage_Info" and "OpenAIChatCompletion_Usage_Log")
0
rozek avatar
rozek
Authorization_from_SQLite_Test
HTTP
Here are some tests for val Authorization_from_SQLite Test Cases Positive Test Cases Valid credentials with existing user TableName: "Authorization_from_SQLite_Test" Database content: UserId "alice", PasswordHash "{PBKDF2}10000$salt123$hashedPassword123" Authorization header: "Basic " + btoa("alice:correctPassword") Expected result: true Valid credentials with case-insensitive UserId TableName: "Authorization_from_SQLite_Test" Database content: UserId "Bob", PasswordHash "{PBKDF2}10000$salt456$hashedPassword456" Authorization header: "Basic " + btoa("bob:correctPassword") Expected result: true Negative Test Cases Invalid password TableName: "Authorization_from_SQLite_Test" Database content: UserId "charlie", PasswordHash "{PBKDF2}10000$salt789$hashedPassword789" Authorization header: "Basic " + btoa("charlie:wrongPassword") Expected result: false No Authorization header TableName: "Authorization_from_SQLite_Test" Database content: UserId "david", PasswordHash "{PBKDF2}10000$saltABC$hashedPasswordABC" Authorization header: undefined Expected result: false Non-existent user TableName: "Authorization_from_SQLite_Test" Database content: (empty) Authorization header: "Basic " + btoa("eve:anyPassword") Expected result: false Error Cases Invalid table name TableName: "1INVALID" Authorization header: "Basic " + btoa("frank:password") Expected result: Error thrown Edge Cases Empty string as password TableName: "Authorization_from_SQLite_Test" Database content: UserId "grace", PasswordHash "{PBKDF2}10000$saltDEF$hashedEmptyPassword" Authorization header: "Basic " + btoa("grace:") Expected result: true (if the empty password hashes correctly) Non-Basic authorization type TableName: "Authorization_from_SQLite_Test" Database content: UserId "henry", PasswordHash "{PBKDF2}10000$saltGHI$hashedPasswordGHI" Authorization header: "Bearer " + btoa("henry:password") Expected result: false Malformed PasswordHash in database TableName: "Authorization_from_SQLite_Test" Database content: UserId "isaac", PasswordHash "malformedHash" Authorization header: "Basic " + btoa("isaac:password") Expected result: false Very long UserId (at 256 character limit) TableName: "Authorization_from_SQLite_Test" Database content: UserId (256 'a' characters), PasswordHash "{PBKDF2}10000$saltJKL$hashedPasswordJKL" Authorization header: "Basic " + btoa("a".repeat(256) + ":password") Expected result: true (if password is correct) UserId exceeding 256 characters TableName: "Authorization_from_SQLite_Test" Authorization header: "Basic " + btoa("a".repeat(257) + ":password") Expected result: false (as it shouldn't exist in the database) Empty UserId TableName: "Authorization_from_SQLite_Test" Authorization header: "Basic " + btoa(":password") Expected result: false
0
rozek avatar
rozek
Authorization_from_SQLite
Script
Some tests can be found in val Authorization_from_SQLite_Test
0
rozek avatar
rozek
Authorization_from_Blob_Test
HTTP
Here are some tests for val Authorization_from_Blob Test Cases Here are the rewritten test cases to fit the generated code that uses Blob storage instead of environment variables: Positive Test Cases Valid token with defined Blob BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: "Bearer secret123" Mode: "forbid-if-not-defined" Expected result: true Valid token with allow-if-not-defined mode BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: "Bearer secret123" Mode: "allow-if-not-defined" Expected result: true Valid token with missing mode (default behavior) BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: "Bearer secret123" Mode: undefined Expected result: true Negative Test Cases Invalid token BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: "Bearer wrongtoken" Mode: "forbid-if-not-defined" Expected result: false No Authorization header BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: undefined Mode: "forbid-if-not-defined" Expected result: false Blob not defined, forbid mode BlobName: "UNDEFINED_TOKEN" Blob value: undefined Authorization header: "Bearer anytoken" Mode: "forbid-if-not-defined" Expected result: false Blob not defined, allow mode BlobName: "UNDEFINED_TOKEN" Blob value: undefined Authorization header: "Bearer anytoken" Mode: "allow-if-not-defined" Expected result: true Error Cases Invalid Blob name BlobName: "1INVALID" Blob value: "secret123" Authorization header: "Bearer secret123" Mode: "forbid-if-not-defined" Expected result: Error thrown Invalid Mode BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: "Bearer secret123" Mode: "invalid-mode" Expected result: Error thrown Edge Cases Empty string as token BlobName: "EMPTY_TOKEN" Blob value: "" Authorization header: "Bearer " Mode: "forbid-if-not-defined" Expected result: true Case-sensitive token comparison BlobName: "CASE_TOKEN" Blob value: "Secret123" Authorization header: "Bearer secret123" Mode: "forbid-if-not-defined" Expected result: false Non-Bearer authorization type BlobName: "VALID_TOKEN" Blob value: "secret123" Authorization header: "Basic secret123" Mode: "forbid-if-not-defined" Expected result: false
0
rozek avatar
rozek
Authorization_from_Blob
Script
some tests can be found in val Authorization_from_Blob_Test
0
rozek avatar
rozek
Authorization_from_EnvVar_Test
HTTP
Here are some tests for val Authorization_from_EnvVar Test Cases Positive Test Cases Valid token with defined environment variable EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: "Bearer secret123" Mode: "forbid-if-not-defined" Expected result: true Valid token with allow-if-not-defined mode EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: "Bearer secret123" Mode: "allow-if-not-defined" Expected result: true Valid token with missing mode (default behavior) EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: "Bearer secret123" Mode: undefined Expected result: true Negative Test Cases Invalid token EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: "Bearer wrongtoken" Mode: "forbid-if-not-defined" Expected result: false No Authorization header EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: undefined Mode: "forbid-if-not-defined" Expected result: false Environment variable not defined, forbid mode EnvVarName: "UNDEFINED_TOKEN" Environment variable value: undefined Authorization header: "Bearer anytoken" Mode: "forbid-if-not-defined" Expected result: false Environment variable not defined, allow mode EnvVarName: "UNDEFINED_TOKEN" Environment variable value: undefined Authorization header: "Bearer anytoken" Mode: "allow-if-not-defined" Expected result: true Error Cases Invalid environment variable name EnvVarName: "1INVALID" Environment variable value: "secret123" Authorization header: "Bearer secret123" Mode: "forbid-if-not-defined" Expected result: Error thrown Invalid Mode EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: "Bearer secret123" Mode: "invalid-mode" Expected result: Error thrown Edge Cases Empty string as token EnvVarName: "EMPTY_TOKEN" Environment variable value: "" Authorization header: "Bearer " Mode: "forbid-if-not-defined" Expected result: true Case-sensitive token comparison EnvVarName: "CASE_TOKEN" Environment variable value: "Secret123" Authorization header: "Bearer secret123" Mode: "forbid-if-not-defined" Expected result: false Non-Bearer authorization type EnvVarName: "VALID_TOKEN" Environment variable value: "secret123" Authorization header: "Basic secret123" Mode: "forbid-if-not-defined" Expected result: false
0
rozek avatar
rozek
Authorization_from_EnvVar
Script
Some tests can be find in val Authorization_from_EnvVar_Tests
0
rozek avatar
rozek
PBKDF2_Generator
HTTP
This is a simple generator for PBKDF2 password hashes. It can be used to manually generate these hashes and store it in a password file if no other mechanism for doing so is available. There is no specific required format for the password. For the number of iterations, values from 100000 up to 999999 are accepted - in these days, values of 600000 or higher are recommended. The final output has the format "{PBKDF2}<iterations>$<salt>$<hash>" where salt and hash are Base64-encoded. You may copy it directly or use salt and hash separately if you need a different format. The applet uses WebCrypto and runs entirely within the browser.
0
rozek avatar
rozek
UUIDv4_Generator
HTTP
This is a simple generator for UUIDs of Type 4. While it may already be useful by itself, it has primarily been made in order to provide some data for the InvocationTracker and its viewer. This means that every invocation of the UUIDv4 Generator is tracked - but only by incrementing an internal counter, no IP addresses or any other details are stored
0
rozek avatar
rozek
InvocationTracker_Test
HTTP
Here are some tests for val InvocationTracker Test Cases Constructor test with valid inputs tests creating a new InvocationTracker instance with valid name and granularity Constructor test with invalid name verifies that creating an InvocationTracker with an invalid name throws an error Constructor test existing table verifies that creating an InvocationTracker with an already existing table does not modify that table Granularity method test checks if the Granularity() method returns the correct initial granularity value setGranularity method test tests setting a new granularity value and verifies it's updated correctly increment method test verifies that the increment() method correctly increases the invocation count InvocationsInSpan method test tests retrieving invocations within a specific time span, including multiple time periods totalInvocationsInSpan method test checks if the total number of invocations within a given time span is calculated correctly reset method test verifies that the reset() method clears all recorded invocations
0
rozek avatar
rozek
InvocationTracker
Script
If you make a val public, you may probably also want to see how often that val is used - perhaps even including some statistics which show how often that val was called in a given time span. This is exactly what the "InvocationTracker" was written for. Simply include a call to the "InvocationTracker" in your val, and from then on any invocations will be tracked in an sqlite table allowing you to easily calculate how often the val was used in total or get the time course of calls. Usage Example Using an InvocationTracker (within the val that should be monitored) is quite simple: import { InvocationTracker } from 'https://esm.town/v/rozek/InvocationTracker' const TrackingTable = 'xxx' // enter name of sqlite table that can be used const Granularity = 15*60*1000 // how precisely should be logged? ;(async () => { const Tracker = await InvocationTracker.new(TrackingTable,Granularity) await Tracker.increment() // logs this invocation ... now continue as usual })() Later, you may then use the "InvocationTracker" to provide you with some statistics: import { InvocationTracker } from 'https://esm.town/v/rozek/InvocationTracker' const TrackingTable = 'xxx' // enter name of sqlite table that can be used ;(async () => { const Tracker = await InvocationTracker.new(TrackingTable,Granularity) /**** define the time span that interests you ****/ const from = new Date('xxx').getTime() // enter start date of your time span const to = Date.now() // here we are interested in all invocations until now /**** get the total number of invocations in the given time span ****/ const totalInvocations = await Tracker.totalInvocationsInSpan(from,to) /**** get more information about when your val was called over time ****/ const Invocations = await Tracker.InvocationsInSpan(from,to) // format: [{ Time,Invocations },...] with the given granularity // only times with actual invocations are listed, idle times are skipped })() The "InvocationTracker" is designed to be accessed simultaneously from multiple concurrently running vals without interfering with each other. API Reference static async new (Name:string, Granularity:number = 15*60*1000):Promise<InvocationTracker> creates a new "InvocationTracker" instance. Name must match /^[a-z_][0-9a-z_]+$/i , Granularity is the time resolution in milliseconds async Granularity ():Promise<number> returns the current time resolution in milliseconds async setGranularity (newGranularity:number):Promise<void> sets a new time resolution (in milliseconds). newGranularity must be an integer >= 1 async reset ():Promise<void> clears all recorded invocations async increment ():Promise<void> increments the invocation count for the current time period async InvocationsInSpan (from:number, to:number):Promise<{ Time:number, Invocations:number }[]> returns a list of invocation counts within the specified time span. from and to are Unix timestamps in milliseconds async totalInvocationsInSpan (from:number, to:number):Promise<number> returns the total number of invocations within the specified time span. from and to are Unix timestamps in milliseconds Tests Some tests can be found in val InvocationTracker_Test
0