Database Lookup#
๐ Overview#
The STALCRAFT API uses internal identifiers like "zyv9", but applications typically need to search by item names.
DatabaseLookup solves this by maintaining a local, synchronized copy of the official game database with fuzzy search capabilities.
Key Features#
๐Synchronization: with the official stalcraft-database repository๐Fuzzy search: handling typos and partial matchesโกIn-memory caching: for instant queries (~0.0001 seconds after sync)๐ฆMultiple data types: items, achievements, and character stats๐Lazy updates: checks for changes when requested (configurable interval)
How It Works#
DatabaseLookup downloads compressed JSON indexes on first use and caches them in memory.
Searches use fuzzy matching for typos and partial names. When the configured TTL expires, the next request automatically updates the cache if the remote database has changed.
When to Use#
Use DatabaseLookup to convert names to API internal IDs, build search functionality, or retrieve detailed item information and icons.
๐ Core Concepts#
Realms#
Game data exists in two separate versions: ru and global.
Most items are the same, but some are realmโspecific.
Defaults to ru.
Data Source#
The library synchronizes with the official stalcraft-database GitHub repository. Index files are used: listing.json (items), achievements.json, and stats.json.
Fuzzy Search#
Search uses Nโgram tokenization to handle typos, partial names, and different languages.
The threshold parameter (0.0 โ 1.0) controls match strictness lower values return more results, higher values only close matches.
Defaults to 0.2.
Caching & Synchronization#
Commit freshness: The remote commit hash is cached for stale_time seconds. If this time expires, the next method call will check GitHub for changes.
Asset cache: Downloaded item details (JSON) and icons (PNG) are stored in memory for asset_ttl seconds.
Update behavior (If a newer commit is found):
sync_on_update=True(default) โ All indexes reload.sync_on_update=Falseโ Only the accessed index reloads.
Tip
stale_time=0 disables automatic update checks.๐ Initial Setup#
Create a DatabaseLookup with default settings.
It will be configured for the ru realm, indexes considered stale after 15 minutes (stale_time=900) and caching assets for 24 hours (asset_ttl=86400).
from scapi import DatabaseLookup, GitHubClient
import asyncio
import os
# Production use REQUIRES a GitHub token
github = GitHubClient(token=os.getenv("GITHUB_TOKEN"))
lookup = DatabaseLookup(github=github)
async def main():
# Initial sync downloads and caches indexes
await lookup.sync()
# Now ready for instant searches
results = await lookup.search("AK-105")
print(f"Found {len(results)} items")
asyncio.run(main())
Tip
Call sync() once when your application starts.
It downloads JSON files from GitHub, caches them locally, and builds an inโmemory search index.
Sync Realm#
By default, sync() updates only the default realm (instance realm parameter or Config.REALM).
To synchronize both realms, pass a keyword from ALL_REALMS_KEYWORDS (e.g., "all").
# Sync only the default realm ("ru")
await lookup.sync()
# Sync both realms ("ru" + "global")
await lookup.sync(realm="all")
# Sync a specific realm
await lookup.sync(realm="global")
The ALL_REALMS_KEYWORDS includes ("all", "any", "*") for convenience.
Sync Strategy#
Choose settings based on how your application runs.
Longโrunning service (web app, bot):
lookup = DatabaseLookup(
stale_time=300, # Indexes considered stale after 5 minutes
sync_on_update=True, # Reload all indexes if an update is found
)
Script or CLI tool:
lookup = DatabaseLookup(
stale_time=0, # Indexes never considered stale
sync_on_update=False, # Update only accessed indexes
)
# Sync manually if you need fresh data
await lookup.sync(force=True)
Partial Index Updates
sync_on_update=False, indexes are loaded onโdemand when first accessed.achievements.json) when you only need listing.json.sync_on_update=True (default), all indexes are refreshed when any update is detected๐ Search Workflow#
Standard Pipeline#
Most operations follow this pattern: search โ extract ID/paths โ fetch details or call API.
# Search for an item
result = await lookup.find_one("AK-105")
if not result:
print("Item not found")
return
# Extract the internal ID
item_id = result.id # "zz2rn"
item_path = result.data["data"] # "/items/weapon/assault_rifle/zz2rn.json"
# Use the ID with an API client
client = AppClient(token=os.getenv("APP_TOKEN"))
lots = await client.auction(item_id).lots(limit=5)
# Or fetch detailed item information
details = await lookup.item_info(item_path)
Object Lookup object contains id, data, and score. The data field varies by index type but always includes the relevant paths and metadata for that entity type.
Different Data Types#
Specify the filename parameter to search achievements or stats instead of items.
from scapi import IndexFile
# Search achievement
achievement = await lookup.find_one(
"Wretch",
filename="achievements.json" # or IndexFile.ACHIEVEMENTS
)
# Search character stats
stats = await lookup.find_one(
"Piggies",
filename=IndexFile.STATS, # you can use enum to avoid mistypes
)
Getting Entity Data by ID#
Use get_entity() when you already have an internal ID (e.g., from an API response) and need its display information.
# Get achievement data by ID
achievement = await lookup.get_entity("operations_naked_crew", filename="achievements.json")
if achievement:
title = achievement.get("title", {}).get("lines", {}).get("en")
print(f"Achievement: {title}") # "Wretch"
# Get stat name by ID
stat = await lookup.get_entity("reg-tim", filename="stats.json")
if stat:
name = stat.get("name", {}).get("lines", {}).get("en")
print(f"Stat: {name}") # Arrived in the Zone
Retrieving All Entities#
Use get_all() to fetch the complete dictionary of entities for batch processing or analysis.
# Get all stats entities
stats = await lookup.get_all(filename="stats.json")
grouped = {}
for stat in stats.values():
category = stat.get("category", "UNCATEGORIZED")
grouped.setdefault(category, []).append(stat)
for category in sorted(grouped):
names = sorted([stat["name"]["lines"]["ru"] for stat in grouped[category]])
print(f"{category}: {', '.join(names)}")
Item Detailed Information#
Method item_info() fetches the complete JSON of an item, including stats, descriptions, and upgrade variants.
# Get base item data
info = await lookup.item_info("/items/weapon/assault_rifle/zz2rn.json")
# Get an upgraded item version (levels 0โ15)
info = await lookup.item_info(
"/items/weapon/assault_rifle/zz2rn.json",
upgrade_level=10
)
Method item_icon() downloads the item icon as PNG bytes.
icon = await lookup.item_icon("/icons/weapon/assault_rifle/zz2rn.png")
with open("ak105.png", "wb") as fp:
fp.write(icon)
Network Requests
Both item_info() and item_icon() perform HTTP requests to GitHub (unless file is already cached).
For frequent use, provide a GitHub token to your GitHubClient.
See GitHub documentation for personal access token creation.
โ๏ธ Advanced Configuration#
Custom GitHub Client#
Important
DatabaseLookup without a token is for testing only.from scapi import DatabaseLookup, GitHubClient
# Create GitHub client with token
github = GitHubClient(token=os.getenv("GHP_ACCESS_TOKEN"))
# Pass it to the lookup
lookup = DatabaseLookup(github=github)
Optimizing Parameters#
Settings should match your applications access pattern. Consider three dimensions:
๐ก Update frequency: How often you need fresh data.
Frequent updates (price monitor, live dashboard): Set
stale_time=300โ900(5โ15 minutes). The lookup will check GitHub regularly and reload data when changes are detected.Infrequent updates (static analysis, occasional reports): Set
stale_time=3600+(1+ hour) orstale_time=0and callsync(force=True)manually.
๐ Index usage: Which parts of the database you actually use.
Multiple index types:
sync_on_update=Trueensures all indexes stay in sync when any one updates.Single index type:
sync_on_update=Falseprevents downloading unused indexes likeachievements.json.
๐พ Asset cache lifetime: How long you can tolerate cached data.
Long cache (24+ hours): Suitable for background jobs where momentary staleness is acceptable. Increase
asset_ttl.Short cache (minutes): For realโtime applications where data must be recent. Decrease
asset_ttl.Memory tradeโoff: Higher
asset_ttlandasset_capacitykeep more data in RAM, improving speed at the cost of memory usage.
Tip
There is no universal โbestโ setting. Adjust parameters based on how often your data changes, which indexes you query, and how fresh the results need to be.
๐จ Common Issues#
Problem |
Solution |
|---|---|
GitHub rate limit errors |
Provide GitHub personal access token to |
Item not found in search |
Lower the threshold parameter (e.g., to |
Search returns irrelevant matches |
Increase the threshold (e.g., to |
Data seems stale / not updating |
Reduce stale_time or call |
High memory usage |
Decrease |
Sync is slow on startup |
Expected for first sync (1โ10 seconds). Provide a GitHub token to increase download speed by reducing authentication checks and lift rate limits. |
Methods |
These methods download files from GitHub. Ensure a token is provided and consider caching results in your application. |
โฉ Whatโs Next#
Continue with:
API Clients Guide โ Use tokens with AppClient and UserClient.
Authentication Guide โ Register application and get tokens