diff --git a/python/speech_recognition_with_huggingface/.gitignore b/python/speech_recognition_with_huggingface/.gitignore new file mode 100644 index 00000000..4dd59cb5 --- /dev/null +++ b/python/speech_recognition_with_huggingface/.gitignore @@ -0,0 +1,117 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ +env/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# VS Code +.vscode/ + +# Appwrite +appwrite/ \ No newline at end of file diff --git a/python/speech_recognition_with_huggingface/README.md b/python/speech_recognition_with_huggingface/README.md new file mode 100644 index 00000000..2ad77bd9 --- /dev/null +++ b/python/speech_recognition_with_huggingface/README.md @@ -0,0 +1,148 @@ +# Speech Recognition with Hugging Face + + +This function uses the Hugging Face API to perform speech recognition. It takes an audio file from Appwrite storage and sends it to the Hugging Face API for speech recognition. The API returns the text and records it in the database. This function also supports receiving document events from the Appwrite Database. + + +## 🧰 Usage + + +### POST / + + +**Parameters** +| Name | Description | Location | Type | Sample Value | +|------------|-------------|----------|--------|--------------| +| fileId | Appwrite File ID of audio file | Body | String | `65c6319c5f34dc9638ec` | + + +This function also accepts body of a file event from Appwrite Storage. + + +**Response** + + +Sample `200` Response: + + +Text from the audio file is recognized and stored in the database. + + +```json +{ + "text": " going along slushy country roads and speaking to damp audiences in draughty schoolrooms day after day for a fortnight he'll have to put in an appearance at some place of worship on sunday morning and he can come to us immediately afterwards" +} +``` + + +Sample `404` Response: + + +```json +{ + "error": "File not found" +} +``` + + +## ⚙️ Configuration + + +| Setting | Value | +| ----------------- | ------------------------------ | +| Runtime | Python (3.12) | +| Entrypoint | `src/main.py` | +| Build Commands | `npm install && npm run setup` | +| Permissions | `any` | +| Timeout (Seconds) | 15 | +| Events | `buckets.*.files.*.create` | + + +## Prerequisites +- [Appwrite](https://appwrite.io/) account and project +- [Hugging Face](https://huggingface.co/) account and access token + + +## 🔒 Environment Variables + + +### APPWRITE_BUCKET_ID + + +The ID of the bucket where audio is stored. + + +| Question | Answer | +| ------------ | ------------------- | +| Required | No | +| Sample Value | `speech_recogition` | + + +### APPWRITE_DATABASE_ID + + +The ID of the database where the responses are stored. + + +| Question | Answer | +| ------------ | ------ | +| Required | No | +| Sample Value | `ai` | + + +### APPWRITE_COLLECTION_ID + + +The ID of the collection where the responses are stored. + + +| Question | Answer | +| ------------ | ------------------- | +| Required | No | +| Sample Value | `speech_recogition` | + + +### HUGGINGFACE_ACCESS_TOKEN + + +Secret for sending requests to the Hugging Face API. + + +| Question | Answer | +| ------------- | ----------------------------------------------------------------------------------------------------- | +| Required | Yes | +| Sample Value | `hf_x2a...` | +| Documentation | [Hugging Face: API tokens](https://huggingface.co/docs/api-inference/en/quicktour#get-your-api-token) | + + + + +Create a `.env` file in the `src` directory and add the following environment variables: + + + ```properties + APPWRITE_ENDPOINT=http://localhost/v1 <---- set to this if you selected all default values when running appwrite locally through docker + APPWRITE_API_KEY=your_appwrite_api_key + APPWRITE_PROJECT_ID=your_appwrite_project_id + HUGGINGFACE_ACCESS_TOKEN=your_huggingface_access_token + APPWRITE_DATABASE_ID=ai + APPWRITE_COLLECTION_ID=speech_recognition + APPWRITE_BUCKET_ID=speech_recognition + ``` + +## Running the Application + +To process an audio file for speech recognition, you can use the `main.py` script. Ensure your Appwrite function is set up to handle HTTP requests and call the `process_audio` function. + + +## Dependencies + +- pip install appwrite +- pip install huggingface_hub +- pip install python-dotenv + + +## License + + +This project is licensed under the MIT License. diff --git a/python/speech_recognition_with_huggingface/requirements.txt b/python/speech_recognition_with_huggingface/requirements.txt new file mode 100644 index 00000000..2b55ced1 --- /dev/null +++ b/python/speech_recognition_with_huggingface/requirements.txt @@ -0,0 +1,3 @@ +appwrite +huggingface_hub +python-dotenv diff --git a/python/speech_recognition_with_huggingface/src/__pycache__/myappwrite.cpython-312.pyc b/python/speech_recognition_with_huggingface/src/__pycache__/myappwrite.cpython-312.pyc new file mode 100644 index 00000000..b1292d2f Binary files /dev/null and b/python/speech_recognition_with_huggingface/src/__pycache__/myappwrite.cpython-312.pyc differ diff --git a/python/speech_recognition_with_huggingface/src/__pycache__/utils.cpython-312.pyc b/python/speech_recognition_with_huggingface/src/__pycache__/utils.cpython-312.pyc new file mode 100644 index 00000000..75211a89 Binary files /dev/null and b/python/speech_recognition_with_huggingface/src/__pycache__/utils.cpython-312.pyc differ diff --git a/python/speech_recognition_with_huggingface/src/appwrite/docker-compose.yml b/python/speech_recognition_with_huggingface/src/appwrite/docker-compose.yml new file mode 100644 index 00000000..f22684cd --- /dev/null +++ b/python/speech_recognition_with_huggingface/src/appwrite/docker-compose.yml @@ -0,0 +1,888 @@ +x-logging: &x-logging + logging: + driver: 'json-file' + options: + max-file: '5' + max-size: '10m' +services: + traefik: + image: traefik:2.11 + container_name: appwrite-traefik + <<: *x-logging + command: + - --providers.file.directory=/storage/config + - --providers.file.watch=true + - --providers.docker=true + - --providers.docker.exposedByDefault=false + - --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`appwrite`) + - --entrypoints.appwrite_web.address=:80 + - --entrypoints.appwrite_websecure.address=:443 + restart: unless-stopped + ports: + - 80:80 + - 443:443 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-config:/storage/config:ro + - appwrite-certificates:/storage/certificates:ro + depends_on: + - appwrite + networks: + - gateway + - appwrite + + appwrite: + image: appwrite/appwrite:1.6.0 + container_name: appwrite + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + labels: + - traefik.enable=true + - traefik.constraint-label-stack=appwrite + - traefik.docker.network=appwrite + - traefik.http.services.appwrite_api.loadbalancer.server.port=80 + #http + - traefik.http.routers.appwrite_api_http.entrypoints=appwrite_web + - traefik.http.routers.appwrite_api_http.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite_api_http.service=appwrite_api + # https + - traefik.http.routers.appwrite_api_https.entrypoints=appwrite_websecure + - traefik.http.routers.appwrite_api_https.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite_api_https.service=appwrite_api + - traefik.http.routers.appwrite_api_https.tls=true + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + - appwrite-functions:/storage/functions:rw + depends_on: + - mariadb + - redis +# - clamav + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_LOCALE + - _APP_CONSOLE_WHITELIST_ROOT + - _APP_CONSOLE_WHITELIST_EMAILS + - _APP_CONSOLE_SESSION_ALERTS + - _APP_CONSOLE_WHITELIST_IPS + - _APP_CONSOLE_HOSTNAMES + - _APP_SYSTEM_EMAIL_NAME + - _APP_SYSTEM_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY + - _APP_SYSTEM_RESPONSE_FORMAT + - _APP_OPTIONS_ABUSE + - _APP_OPTIONS_ROUTER_PROTECTION + - _APP_OPTIONS_FORCE_HTTPS + - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_DOMAIN_FUNCTIONS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_SMTP_HOST + - _APP_SMTP_PORT + - _APP_SMTP_SECURE + - _APP_SMTP_USERNAME + - _APP_SMTP_PASSWORD + - _APP_USAGE_STATS + - _APP_STORAGE_LIMIT + - _APP_STORAGE_PREVIEW_LIMIT + - _APP_STORAGE_ANTIVIRUS + - _APP_STORAGE_ANTIVIRUS_HOST + - _APP_STORAGE_ANTIVIRUS_PORT + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + - _APP_FUNCTIONS_SIZE_LIMIT + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_BUILD_TIMEOUT + - _APP_FUNCTIONS_CPUS + - _APP_FUNCTIONS_MEMORY + - _APP_FUNCTIONS_RUNTIMES + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_LOGGING_CONFIG + - _APP_MAINTENANCE_INTERVAL + - _APP_MAINTENANCE_DELAY + - _APP_MAINTENANCE_RETENTION_EXECUTION + - _APP_MAINTENANCE_RETENTION_CACHE + - _APP_MAINTENANCE_RETENTION_ABUSE + - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY + - _APP_MAINTENANCE_RETENTION_SCHEDULES + - _APP_SMS_PROVIDER + - _APP_SMS_FROM + - _APP_GRAPHQL_MAX_BATCH_SIZE + - _APP_GRAPHQL_MAX_COMPLEXITY + - _APP_GRAPHQL_MAX_DEPTH + - _APP_VCS_GITHUB_APP_NAME + - _APP_VCS_GITHUB_PRIVATE_KEY + - _APP_VCS_GITHUB_APP_ID + - _APP_VCS_GITHUB_WEBHOOK_SECRET + - _APP_VCS_GITHUB_CLIENT_SECRET + - _APP_VCS_GITHUB_CLIENT_ID + - _APP_MIGRATIONS_FIREBASE_CLIENT_ID + - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET + - _APP_ASSISTANT_OPENAI_API_KEY + + appwrite-console: + <<: *x-logging + container_name: appwrite-console + image: appwrite/console:5.0.12 + restart: unless-stopped + networks: + - appwrite + labels: + - "traefik.enable=true" + - "traefik.constraint-label-stack=appwrite" + - "traefik.docker.network=appwrite" + - "traefik.http.services.appwrite_console.loadbalancer.server.port=80" + #ws + - traefik.http.routers.appwrite_console_http.entrypoints=appwrite_web + - traefik.http.routers.appwrite_console_http.rule=PathPrefix(`/console`) + - traefik.http.routers.appwrite_console_http.service=appwrite_console + # wss + - traefik.http.routers.appwrite_console_https.entrypoints=appwrite_websecure + - traefik.http.routers.appwrite_console_https.rule=PathPrefix(`/console`) + - traefik.http.routers.appwrite_console_https.service=appwrite_console + - traefik.http.routers.appwrite_console_https.tls=true + + appwrite-realtime: + image: appwrite/appwrite:1.6.0 + entrypoint: realtime + container_name: appwrite-realtime + <<: *x-logging + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.constraint-label-stack=appwrite" + - "traefik.docker.network=appwrite" + - "traefik.http.services.appwrite_realtime.loadbalancer.server.port=80" + #ws + - traefik.http.routers.appwrite_realtime_ws.entrypoints=appwrite_web + - traefik.http.routers.appwrite_realtime_ws.rule=PathPrefix(`/v1/realtime`) + - traefik.http.routers.appwrite_realtime_ws.service=appwrite_realtime + # wss + - traefik.http.routers.appwrite_realtime_wss.entrypoints=appwrite_websecure + - traefik.http.routers.appwrite_realtime_wss.rule=PathPrefix(`/v1/realtime`) + - traefik.http.routers.appwrite_realtime_wss.service=appwrite_realtime + - traefik.http.routers.appwrite_realtime_wss.tls=true + networks: + - appwrite + depends_on: + - mariadb + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPTIONS_ABUSE + - _APP_OPTIONS_ROUTER_PROTECTION + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_USAGE_STATS + - _APP_LOGGING_CONFIG + + appwrite-worker-audits: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-audits + <<: *x-logging + container_name: appwrite-worker-audits + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + + appwrite-worker-webhooks: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-webhooks + <<: *x-logging + container_name: appwrite-worker-webhooks + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_EMAIL_SECURITY + - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_LOGGING_CONFIG + + appwrite-worker-deletes: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-deletes + <<: *x-logging + container_name: appwrite-worker-deletes + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + - appwrite-functions:/storage/functions:rw + - appwrite-builds:/storage/builds:rw + - appwrite-certificates:/storage/certificates:rw + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + - _APP_LOGGING_CONFIG + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_MAINTENANCE_RETENTION_ABUSE + - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_EXECUTION + + appwrite-worker-databases: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-databases + <<: *x-logging + container_name: appwrite-worker-databases + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + + appwrite-worker-builds: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-builds + <<: *x-logging + container_name: appwrite-worker-builds + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-functions:/storage/functions:rw + - appwrite-builds:/storage/builds:rw + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + - _APP_VCS_GITHUB_APP_NAME + - _APP_VCS_GITHUB_PRIVATE_KEY + - _APP_VCS_GITHUB_APP_ID + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_BUILD_TIMEOUT + - _APP_FUNCTIONS_CPUS + - _APP_FUNCTIONS_MEMORY + - _APP_FUNCTIONS_SIZE_LIMIT + - _APP_OPTIONS_FORCE_HTTPS + - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS + - _APP_DOMAIN + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + + appwrite-worker-certificates: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-certificates + <<: *x-logging + container_name: appwrite-worker-certificates + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_DOMAIN_FUNCTIONS + - _APP_EMAIL_CERTIFICATES + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + + appwrite-worker-functions: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-functions + <<: *x-logging + container_name: appwrite-worker-functions + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + - openruntimes-executor + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_OPTIONS_FORCE_HTTPS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_BUILD_TIMEOUT + - _APP_FUNCTIONS_CPUS + - _APP_FUNCTIONS_MEMORY + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_USAGE_STATS + - _APP_DOCKER_HUB_USERNAME + - _APP_DOCKER_HUB_PASSWORD + - _APP_LOGGING_CONFIG + + appwrite-worker-mails: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-mails + <<: *x-logging + container_name: appwrite-worker-mails + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_SYSTEM_EMAIL_NAME + - _APP_SYSTEM_EMAIL_ADDRESS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_SMTP_HOST + - _APP_SMTP_PORT + - _APP_SMTP_SECURE + - _APP_SMTP_USERNAME + - _APP_SMTP_PASSWORD + - _APP_LOGGING_CONFIG + + appwrite-worker-messaging: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-messaging + <<: *x-logging + container_name: appwrite-worker-messaging + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-uploads:/storage/uploads:rw + depends_on: + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + - _APP_SMS_FROM + - _APP_SMS_PROVIDER + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + + appwrite-worker-migrations: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-migrations + <<: *x-logging + container_name: appwrite-worker-migrations + restart: unless-stopped + networks: + - appwrite + depends_on: + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_EMAIL_SECURITY + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + - _APP_MIGRATIONS_FIREBASE_CLIENT_ID + - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET + + appwrite-task-maintenance: + image: appwrite/appwrite:1.6.0 + entrypoint: maintenance + <<: *x-logging + container_name: appwrite-task-maintenance + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_DOMAIN_FUNCTIONS + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_MAINTENANCE_INTERVAL + - _APP_MAINTENANCE_RETENTION_EXECUTION + - _APP_MAINTENANCE_RETENTION_CACHE + - _APP_MAINTENANCE_RETENTION_ABUSE + - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY + - _APP_MAINTENANCE_RETENTION_SCHEDULES + + appwrite-worker-usage: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-usage + container_name: appwrite-worker-usage + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_USAGE_STATS + - _APP_LOGGING_CONFIG + - _APP_USAGE_AGGREGATION_INTERVAL + + appwrite-worker-usage-dump: + image: appwrite/appwrite:1.6.0 + entrypoint: worker-usage-dump + <<: *x-logging + container_name: appwrite-worker-usage-dump + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_USAGE_STATS + - _APP_LOGGING_CONFIG + - _APP_USAGE_AGGREGATION_INTERVAL + + appwrite-task-scheduler-functions: + image: appwrite/appwrite:1.6.0 + entrypoint: schedule-functions + container_name: appwrite-task-scheduler-functions + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - mariadb + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-task-scheduler-executions: + image: appwrite/appwrite:1.6.0 + entrypoint: schedule-executions + container_name: appwrite-task-scheduler-executions + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - mariadb + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-task-scheduler-messages: + image: appwrite/appwrite:1.6.0 + entrypoint: schedule-messages + container_name: appwrite-task-scheduler-messages + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - mariadb + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-assistant: + image: appwrite/assistant:0.4.0 + container_name: appwrite-assistant + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + environment: + - _APP_ASSISTANT_OPENAI_API_KEY + + openruntimes-executor: + container_name: openruntimes-executor + hostname: exc1 + <<: *x-logging + restart: unless-stopped + stop_signal: SIGINT + image: openruntimes/executor:0.6.11 + networks: + - appwrite + - runtimes + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-builds:/storage/builds:rw + - appwrite-functions:/storage/functions:rw + # Host mount nessessary to share files between executor and runtimes. + # It's not possible to share mount file between 2 containers without host mount (copying is too slow) + - /tmp:/tmp:rw + environment: + - OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD + - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL + - OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK + - OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME + - OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD + - OPR_EXECUTOR_ENV=$_APP_ENV + - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES + - OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET + - OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG + - OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE + - OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_S3_SECRET=$_APP_STORAGE_S3_SECRET + - OPR_EXECUTOR_STORAGE_S3_REGION=$_APP_STORAGE_S3_REGION + - OPR_EXECUTOR_STORAGE_S3_BUCKET=$_APP_STORAGE_S3_BUCKET + - OPR_EXECUTOR_STORAGE_DO_SPACES_ACCESS_KEY=$_APP_STORAGE_DO_SPACES_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_DO_SPACES_SECRET=$_APP_STORAGE_DO_SPACES_SECRET + - OPR_EXECUTOR_STORAGE_DO_SPACES_REGION=$_APP_STORAGE_DO_SPACES_REGION + - OPR_EXECUTOR_STORAGE_DO_SPACES_BUCKET=$_APP_STORAGE_DO_SPACES_BUCKET + - OPR_EXECUTOR_STORAGE_BACKBLAZE_ACCESS_KEY=$_APP_STORAGE_BACKBLAZE_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_BACKBLAZE_SECRET=$_APP_STORAGE_BACKBLAZE_SECRET + - OPR_EXECUTOR_STORAGE_BACKBLAZE_REGION=$_APP_STORAGE_BACKBLAZE_REGION + - OPR_EXECUTOR_STORAGE_BACKBLAZE_BUCKET=$_APP_STORAGE_BACKBLAZE_BUCKET + - OPR_EXECUTOR_STORAGE_LINODE_ACCESS_KEY=$_APP_STORAGE_LINODE_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_LINODE_SECRET=$_APP_STORAGE_LINODE_SECRET + - OPR_EXECUTOR_STORAGE_LINODE_REGION=$_APP_STORAGE_LINODE_REGION + - OPR_EXECUTOR_STORAGE_LINODE_BUCKET=$_APP_STORAGE_LINODE_BUCKET + - OPR_EXECUTOR_STORAGE_WASABI_ACCESS_KEY=$_APP_STORAGE_WASABI_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_WASABI_SECRET=$_APP_STORAGE_WASABI_SECRET + - OPR_EXECUTOR_STORAGE_WASABI_REGION=$_APP_STORAGE_WASABI_REGION + - OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET + + mariadb: + image: mariadb:10.11 # fix issues when upgrading using: mysql_upgrade -u root -p + container_name: appwrite-mariadb + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-mariadb:/var/lib/mysql:rw + environment: + - MYSQL_ROOT_PASSWORD=${_APP_DB_ROOT_PASS} + - MYSQL_DATABASE=${_APP_DB_SCHEMA} + - MYSQL_USER=${_APP_DB_USER} + - MYSQL_PASSWORD=${_APP_DB_PASS} + - MARIADB_AUTO_UPGRADE=1 + command: 'mysqld --innodb-flush-method=fsync' + + redis: + image: redis:7.2.4-alpine + container_name: appwrite-redis + <<: *x-logging + restart: unless-stopped + command: > + redis-server + --maxmemory 512mb + --maxmemory-policy allkeys-lru + --maxmemory-samples 5 + networks: + - appwrite + volumes: + - appwrite-redis:/data:rw + + # clamav: + # image: appwrite/clamav:1.2.0 + # container_name: appwrite-clamav + # restart: unless-stopped + # networks: + # - appwrite + # volumes: + # - appwrite-uploads:/storage/uploads + +networks: + gateway: + name: gateway + appwrite: + name: appwrite + runtimes: + name: runtimes + +volumes: + appwrite-mariadb: + appwrite-redis: + appwrite-cache: + appwrite-uploads: + appwrite-certificates: + appwrite-functions: + appwrite-builds: + appwrite-config: diff --git a/python/speech_recognition_with_huggingface/src/main.py b/python/speech_recognition_with_huggingface/src/main.py new file mode 100644 index 00000000..b18cff89 --- /dev/null +++ b/python/speech_recognition_with_huggingface/src/main.py @@ -0,0 +1,109 @@ +from huggingface_hub import InferenceClient +from myappwrite import AppwriteService +from utils import throw_if_missing +import os +from dotenv import load_dotenv + +# Load environment variables from .env file +load_dotenv() + + +# Check if the variable is accessible +print("HUGGINGFACE_ACCESS_TOKEN:", os.getenv("HUGGINGFACE_ACCESS_TOKEN")) + + +async def process_audio(req, res, log, error): + """ + Processes an audio file, performs speech-to-text using Hugging Face, and stores results in Appwrite. + :param req: Request object + :param res: Response object + :param log: Logger function + :param error: Error logging function + """ + log("Starting process_audio...") + + + # Ensure required environment variables are set + throw_if_missing(os.environ, ["HUGGINGFACE_ACCESS_TOKEN"]) + log("Hugging Face access token loaded") + + + # Retrieve environment variables or use defaults + database_id = os.getenv("APPWRITE_DATABASE_ID", "ai") + collection_id = os.getenv("APPWRITE_COLLECTION_ID", "speech_recognition") + bucket_id = os.getenv("APPWRITE_BUCKET_ID", "speech_recognition") + log(f"Using database: {database_id}, collection: {collection_id}, bucket: {bucket_id}") + + + # Check that the request method is POST + if req.method != "POST": + log(f"Invalid request method: {req.method}") + return res.json({"ok": False, "error": "Method not allowed"}, status=405) + + + # Retrieve fileId from request + file_id = req.body_json.get("$id") or req.body_json.get("fileId") + if not file_id: + error("Missing fileId") + log("Missing fileId in request") + return res.json({"ok": False, "error": "Bad request, fileId is required"}, status=400) + + + # Validate bucketId + if req.body_json.get("bucketId") and req.body_json["bucketId"] != bucket_id: + error("Invalid bucketId") + log(f"Invalid bucketId: {req.body_json.get('bucketId')}") + return res.json({"ok": False, "error": "Bad request, invalid bucketId"}, status=400) + + + # Initialize Appwrite service + appwrite = AppwriteService(req.headers.get("x-appwrite-key")) + log(f"Appwrite service initialized with key successfully") + + + # Retrieve the file from Appwrite + try: + appwrite.get_file(bucket_id, file_id) + log(f"File {file_id} retrieved successfully") + except Exception as e: + if getattr(e, "code", None) == 404: + error("File not found") + log(f"File {file_id} not found in bucket {bucket_id}") + return res.json({"ok": False, "error": "File not found"}, status=404) + error(f"Failed to retrieve file: {e}") + return res.json({"ok": False, "error": "Bad request, failed to retrieve file"}, status=400) + + # Initialize Hugging Face API + hf = InferenceClient(model='facebook/wav2vec2-base-960h', token=os.getenv('HUGGINGFACE_ACCESS_TOKEN')) + log("Hugging Face Inference Client initialized") + + + # Using Speech Recognition using Hugging Face Inference Client + try: + ''' + log(f"File content type: {type(file)}") + log(f"File keys: {file.keys()}") + ''' + audio_content = appwrite.get_file(bucket_id, file_id) + result = hf.automatic_speech_recognition(audio_content) + log(f"Speech recognition result: {result}") + except Exception as e: + error(f"Failed to recognize speech: {e}") + return res.json({"ok": False, "error": "Failed to recognize speech"}, status=500) + + + # Create a recognition entry in Appwrite database + try: + await appwrite.create_recognition_entry( + database_id, collection_id, file_id, result['text'] + ) + log(f"Recognition entry created for {file_id}") + except Exception as err: + error(f"Appwrite error: {err}") + log(f"Appwrite error: {err}") + return res.json({"ok": False, "error": "Failed to create recognition entry in database"}, status=500) + + + # Return the recognized text as a response + log(f"Returning recognized text for {file_id}") + return res.json({"text": result['text']}) diff --git a/python/speech_recognition_with_huggingface/src/myappwrite.py b/python/speech_recognition_with_huggingface/src/myappwrite.py new file mode 100644 index 00000000..faec7df8 --- /dev/null +++ b/python/speech_recognition_with_huggingface/src/myappwrite.py @@ -0,0 +1,83 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases +from appwrite.services.storage import Storage +from appwrite.id import ID +from dotenv import load_dotenv +import os + + +load_dotenv() + +class AppwriteService: + def __init__(self, api_key): + self.client = Client() + self.client.set_endpoint(os.getenv('APPWRITE_ENDPOINT')) + self.client.set_project(os.getenv('APPWRITE_PROJECT_ID')) + self.client.set_key(api_key) + + + self.databases = Databases(self.client) + self.storage = Storage(self.client) + + + def create_Recognition_Entry(self, database_id, collection_id, audio_id, speech): + self.databases.create_document(database_id, collection_id, ID.unique(), { + 'audio': audio_id, + 'speech': speech, + }) + + + def get_file(self, bucket_id, file_id): + file_content = self.storage.get_file_download(bucket_id, file_id) + return self.storage.get_file(bucket_id, file_id) + + def does_ai_data_exist(self, database_id, collection_id): + try: + self.databases.get(database_id) + self.databases.get_collection(database_id, collection_id) + return True + except: + return False + + + def does_bucket_exist(self, bucket_id): + try: + self.storage.get_bucket(bucket_id) + return True + except: + return False + + + async def setup_ai_database(self, database_id, collection_id): + try: + self.databases.get(database_id) + except: + self.databases.create(database_id, 'AI Database') + + + try: + self.databases.get_collection(database_id, collection_id) + except: + self.databases.create_collection(database_id, collection_id, 'Speech Recognition') + + + try: + self.databases.get_attribute(database_id, collection_id, 'audio') + except: + self.databases.create_string_attribute(database_id, collection_id, 'audio', 64, True) + + + try: + self.databases.get_attribute(database_id, collection_id, 'speech') + except: + self.databases.create_string_attribute(database_id, collection_id, 'speech', 1024, True) + + + async def setup_ai_bucket(self, bucket_id): + try: + self.storage.get_bucket(bucket_id) + except: + self.storage.create_bucket(bucket_id, 'AI') + + + diff --git a/python/speech_recognition_with_huggingface/src/setup.py b/python/speech_recognition_with_huggingface/src/setup.py new file mode 100644 index 00000000..10fcbe2c --- /dev/null +++ b/python/speech_recognition_with_huggingface/src/setup.py @@ -0,0 +1,32 @@ +import os +from myappwrite import AppwriteService +from dotenv import load_dotenv +import asyncio + +load_dotenv() + +async def setup(): + database_id = os.getenv('APPWRITE_DATABASE_ID') + collection_id = os.getenv('APPWRITE_COLLECTION_ID') + bucket_id = os.getenv('APPWRITE_BUCKET_ID') + print('Executing setup script...') + + + appwrite = AppwriteService(os.getenv('APPWRITE_API_KEY')) + + + if appwrite.does_ai_data_exist(database_id, collection_id): + print('Database exists.') + else: + await appwrite.setup_ai_database(database_id, collection_id) + print('Database created.') + + + if appwrite.does_bucket_exist(bucket_id): + print('Bucket exists.') + else: + await appwrite.setup_ai_bucket(bucket_id) + print('Bucket created.') + +if __name__ == "__main__": + asyncio.run(setup()) \ No newline at end of file diff --git a/python/speech_recognition_with_huggingface/src/utils.py b/python/speech_recognition_with_huggingface/src/utils.py new file mode 100644 index 00000000..12b38d1f --- /dev/null +++ b/python/speech_recognition_with_huggingface/src/utils.py @@ -0,0 +1,10 @@ +def throw_if_missing(obj, keys): + """ + Throws an error if any of the keys are missing from the object. + :param obj: Dictionary-like object + :param keys: List of required keys + :raises ValueError: If any keys are missing + """ + missing = [key for key in keys if not obj.get(key)] + if missing: + raise ValueError(f"Missing required fields: {', '.join(missing)}") \ No newline at end of file