Spaces:
Running
Running
Download start.sh from free-apis-collection/markitdown: direct link, hf CLI and curl.
- Browser
- Download file 4.58 kB
-
https://huggingface.co/spaces/free-apis-collection/markitdown/resolve/main/start.sh
- Command line
-
hf download hf://spaces/free-apis-collection/markitdown/start.sh
-
curl -L -o start.sh https://huggingface.co/spaces/free-apis-collection/markitdown/resolve/main/start.sh
4.58 kB
| # ChatCsv&Pdf-Backend β HF Space entrypoint. | |
| # Loads the single `ENV_FILE` secret (verbatim copy of `.env`) into the | |
| # environment, then starts uvicorn. Same pattern as the reference | |
| # huggingface-service start.sh, simplified for this app. | |
| set -euo pipefail | |
| log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; } | |
| # Track pre-existing process env (HF Space Secrets injected by the platform | |
| # take precedence over ENV_FILE entries with the same name). | |
| declare -A _ENV_FROM_PROCESS | |
| for _k in $(compgen -e); do _ENV_FROM_PROCESS["$_k"]=1; done | |
| # Parse a multi-line KEY=VALUE document (ENV_FILE secret value) and export | |
| # each entry. Handles CRLF, blank lines, '#' comments, 'export ' prefixes, | |
| # surrounding quotes, and values containing '=' (split on first '=' only). | |
| # Never logs values β names only. | |
| load_env_document() { | |
| local content="$1" line key val | |
| local _ok=0 _skip=0 _fail=0 | |
| if [[ "$content" != *$'\n'* && "$content" == *'\n'* ]]; then | |
| log "ENV_FILE: no real newlines found β expanding literal \\n sequences" | |
| content="${content//\\n/$'\n'}" | |
| fi | |
| while IFS= read -r line || [ -n "$line" ]; do | |
| line="${line%$'\r'}" | |
| key="${line#"${line%%[![:space:]]*}"}" | |
| [ -n "$key" ] || continue | |
| case "$key" in '#'*) continue ;; esac | |
| if [[ "$key" == 'export '* ]]; then | |
| key="${key#export }" | |
| key="${key#"${key%%[![:space:]]*}"}" | |
| fi | |
| case "$key" in | |
| *=*) val="${key#*=}"; key="${key%%=*}" ;; | |
| *) log "ENV FAIL: malformed line, no '=' found: ${line:0:40}"; _fail=$((_fail+1)); continue ;; | |
| esac | |
| key="${key%"${key##*[![:space:]]}"}" | |
| if ! [[ "$key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then | |
| log "ENV FAIL: invalid variable name '${key:0:40}'"; _fail=$((_fail+1)); continue | |
| fi | |
| val="${val#"${val%%[![:space:]]*}"}" | |
| val="${val%"${val##*[![:space:]]}"}" | |
| case "$val" in | |
| \"*\") val="${val#\"}"; val="${val%\"}" ;; | |
| \'*\') val="${val#\'}"; val="${val%\'}" ;; | |
| esac | |
| if [ -n "${_ENV_FROM_PROCESS[$key]:-}" ]; then | |
| log "ENV SKIP: $key (already set in process environment β keeping existing value)" | |
| _skip=$((_skip+1)) | |
| elif export "$key=$val" 2>/dev/null; then | |
| log "ENV OK: $key"; _ok=$((_ok+1)) | |
| else | |
| log "ENV FAIL: $key (could not export)"; _fail=$((_fail+1)) | |
| fi | |
| done <<< "$content" | |
| log "ENV_FILE load summary: $_ok loaded, $_skip skipped, $_fail failed, $((_ok+_skip+_fail)) total" | |
| } | |
| if [ -n "${ENV_FILE:-}" ]; then | |
| log "ENV_FILE secret detected (${#ENV_FILE} chars) β loading embedded environment" | |
| load_env_document "$ENV_FILE" | |
| else | |
| log "ENV_FILE secret not set β falling back to .env files (local dev) / platform env (HF Secrets)" | |
| [ -f ".env" ] && log ".env file present β pydantic-settings will load it" || log "no .env file β using process environment" | |
| fi | |
| _crit_missing="" | |
| for _v in APPLICATION_MAIN_BACKEND_AUTH_TOKEN REDIS_URL PINECONE_API_KEYS; do | |
| [ -n "${!_v:-}" ] || _crit_missing="$_crit_missing $_v" | |
| done | |
| if [ -n "$_crit_missing" ]; then | |
| log "WARNING: keys not set:$_crit_missing (app still boots; /chat degrades without Pinecone/Redis)" | |
| else | |
| log "Critical keys: all present" | |
| fi | |
| unset _crit_missing _v | |
| log "=== Starting up ===" | |
| log "Python: $(python --version 2>&1)" | |
| log "Working dir: $(pwd)" | |
| mkdir -p "${STORAGE_DIR:-/app/storage}" /app/storage | |
| log "Storage directories: OK" | |
| python -c "import fastapi, uvicorn, httpx, pydantic" 2>/dev/null \ | |
| && log "Core dependencies: OK" \ | |
| || { log "ERROR: missing core dependencies (fastapi/uvicorn/httpx/pydantic)"; exit 1; } | |
| HOST="${HOST:-0.0.0.0}" | |
| PORT="${PORT:-7860}" | |
| log "Self-ping: SELF_PING_ENABLED=${SELF_PING_ENABLED:-true} SELF_PING_URL=${SELF_PING_URL:-'(derived from SPACE_ID)'} interval=${SELF_PING_INTERVAL:-600}s" | |
| _cron_base="${FRONTEND_BASE_URL:-'(missing)'}" | |
| _cron_secret_state="missing"; [ -n "${CRON_SECRET:-}" ] && _cron_secret_state="set" | |
| _cron_v1_state="missing"; [ -n "${EXTERNAL_API_CRON_TOKEN:-}" ] && _cron_v1_state="set" | |
| log "Frontend credit crons: CRON_ENABLED=${CRON_ENABLED:-true} CRON_TIMEZONE=${CRON_TIMEZONE:-'(system)'} FRONTEND_BASE_URL=${_cron_base} /api/cron(${_cron_secret_state}) /api/v1/cron(${_cron_v1_state}) daily=00:00" | |
| unset _cron_base _cron_secret_state _cron_v1_state | |
| log "Starting uvicorn: host=$HOST port=$PORT workers=1 app=app.main:app" | |
| exec python -m uvicorn app.main:app --host "$HOST" --port "$PORT" --workers 1 | |