{"id":30192547,"url":"https://github.com/machinelearningzh/alt-text-generator","last_synced_at":"2025-08-12T23:42:49.368Z","repository":{"id":308703577,"uuid":"1033763416","full_name":"machinelearningZH/alt-text-generator","owner":"machinelearningZH","description":"Automagically generate drafts for German alt texts for web images using AI. ","archived":false,"fork":false,"pushed_at":"2025-08-07T10:31:49.000Z","size":370,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-07T12:26:56.847Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/machinelearningZH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-07T10:01:19.000Z","updated_at":"2025-08-07T10:31:52.000Z","dependencies_parsed_at":"2025-08-07T12:26:59.705Z","dependency_job_id":"f23b3822-c85d-4e71-b5bb-6067f324172c","html_url":"https://github.com/machinelearningZH/alt-text-generator","commit_stats":null,"previous_names":["machinelearningzh/alt-text-generator"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/machinelearningZH/alt-text-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/machinelearningZH%2Falt-text-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/machinelearningZH%2Falt-text-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/machinelearningZH%2Falt-text-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/machinelearningZH%2Falt-text-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/machinelearningZH","download_url":"https://codeload.github.com/machinelearningZH/alt-text-generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/machinelearningZH%2Falt-text-generator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270154213,"owners_count":24536640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-12T23:42:47.199Z","updated_at":"2025-08-12T23:42:49.341Z","avatar_url":"https://github.com/machinelearningZH.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Alt-Text-Generator KTZH\n\n**Automagically generate German alt texts for web images using AI.**\n\n![GitHub License](https://img.shields.io/github/license/machinelearningzh/alt-text-generator)\n[![PyPI - Python](https://img.shields.io/badge/python-v3.10+-blue.svg)](https://github.com/machinelearningzh/alt-text-generator)\n[![GitHub Stars](https://img.shields.io/github/stars/machinelearningZH/alt-text-generator.svg)](https://github.com/machinelearningZH/alt-text-generator/stargazers)\n[![GitHub Issues](https://img.shields.io/github/issues/machinelearningZH/alt-text-generator.svg)](https://github.com/machinelearningZH/alt-text-generator/issues)\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/machinelearningZH/alt-text-generator.svg)](https://img.shields.io/github/issues-pr/machinelearningZH/alt-text-generator)\n[![Current Version](https://img.shields.io/badge/version-0.1.0-green.svg)](https://github.com/statistikZH/alt-text-generator)\n\u003ca href=\"https://github.com/astral-sh/ruff\"\u003e\u003cimg alt=\"linting - Ruff\" class=\"off-glb\" loading=\"lazy\" src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\"\u003e\u003c/a\u003e\n\n![](_imgs/app_ui.png)\n\n## Features\n\n- **Streamlit Web App and CLI Tool**: Input any URL to analyze all images\n- **AI-powered Alt-Text Generation**: German alt-text using LLMs via OpenRouter\n- **Context Analysis**: Considers image content, surrounding text (headings, paragraphs, captions) and existing alt-text\n- **Excel Export**: Export all results as an Excel file\n- **Parallel Processing**: Fast batch processing with configurable worker threads\n- **Multiple Image Formats**: Support for JPEG, PNG, and WebP formats\n- **Batch Processing of Multiple Web Pages**: CLI tool can process URL lists\n\n## Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/statistikZH/alt-text-generator.git\ncd alt-text-generator\n\n# Install uv (if not already installed)\npip3 install uv\n\n# Create virtual environment and install dependencies\nuv venv\nsource .venv/bin/activate  # On macOS/Linux\n# or .venv\\Scripts\\activate  # On Windows\nuv sync\n```\n\n## Configuration\n\nConfigure the **environment variables**:\n\n- The app automatically loads environment variables from `.env` or the configured path in `config.yaml`\n- Set your OpenRouter API key:\n\n```bash\nexport OPENROUTER_API_KEY=\"your_api_key_here\"\n```\n\nOr create a `.env` file in the project root:\n\n```\nOPENROUTER_API_KEY=your_api_key_here\n```\n\nCurrently, the application uses Google Gemini 2.5 Flash via OpenRouter. You can easily change this by simply inserting a different OpenRouter model ID in `config.yaml`.\n\n## Usage\n\n\u003e [!WARNING]  \n\u003e Your data will be processed through [OpenRouter](https://openrouter.ai/) by third parties. Please ensure you only input non-sensitive information.\n\n### Streamlit Web Interface\n\n1. Start the Streamlit app:\n\n```bash\nstreamlit run main.py\n```\n\n2. Open in browser (http://localhost:8501 by default)\n\n### Command-Line Interface\n\nThe CLI provides various processing capabilities with four main commands:\n\n#### Commands Overview\n\n**Using the convenience script (recommended):**\n\n```bash\n# Generate alt-text for a single image\n./generate-alt-text-cli single image.jpg\n\n# Process multiple images from URL list of images\n./generate-alt-text-cli batch urls.txt --output results.json\n\n# Process all images from a webpage\n./generate-alt-text-cli scrape https://example.com --output webpage_images.xlsx --format excel\n\n# Batch process images from multiple webpages\n./generate-alt-text-cli websites website_urls.txt --output all_websites.xlsx --format excel\n```\n\n**Direct usage with uv:**\n\n```bash\nuv run python _cli/cli.py single image.jpg --context \"Swiss building in Zurich from 2025\"\nuv run python _cli/cli.py batch urls.txt --workers 10 --output results.json\n```\n\n#### Detailed Command Reference\n\n##### `single` - Process a Single Image\n\nGenerate alt text for a single image file or URL.\n\n```bash\n./generate-alt-text-cli single \u003cimage\u003e [options]\n```\n\n**Arguments:**\n\n- `image` (required): Path to local image file or image URL\n\n**Options:**\n\n- `--context`, `-c`: Additional context information for the image (default: empty)\n- `--alt-text`, `-a`: Existing alt text to improve upon (default: empty)\n\n**Examples:**\n\n```bash\n./generate-alt-text-cli single photo.jpg\n./generate-alt-text-cli single https://example.com/image.png --context \"Swiss building in Zurich from 2025\"\n./generate-alt-text-cli single image.jpg --alt-text \"Old description\" --context \"Swiss building in Zurich from 2025\"\n```\n\n##### `batch` - Process Multiple Images from URL List\n\nProcess multiple images from a text file containing image URLs.\n\n```bash\n./generate-alt-text-cli batch \u003cfile\u003e [options]\n```\n\n**Arguments:**\n\n- `file` (required): Text file containing image URLs (one per line)\n\n**Options:**\n\n- `--context`, `-c`: Additional context for all images (default: empty)\n- `--workers`, `-w`: Number of parallel workers (default: configured max_workers)\n- `--output`, `-o`: Output file for results\n- `--format`, `-f`: Output format, choices: `json`, `excel` (default: json)\n\n**Examples:**\n\n```bash\n./generate-alt-text-cli batch image_urls.txt\n./generate-alt-text-cli batch urls.txt --output results.json --workers 5\n./generate-alt-text-cli batch urls.txt --context \"Participants of an administration meeting\" --format excel\n```\n\n##### `scrape` - Process Images from a Webpage\n\nScrape and process all images found on a specific webpage.\n\n```bash\n./generate-alt-text-cli scrape \u003curl\u003e [options]\n```\n\n**Arguments:**\n\n- `url` (required): URL of the webpage to scrape for images\n\n**Options:**\n\n- `--workers`, `-w`: Number of parallel workers (default: configured max_workers)\n- `--output`, `-o`: Output file for results\n- `--format`, `-f`: Output format, choices: `json`, `excel` (default: json)\n\n**Examples:**\n\n```bash\n./generate-alt-text-cli scrape https://example.com\n./generate-alt-text-cli scrape https://example.com --output webpage_images.xlsx --format excel\n./generate-alt-text-cli scrape https://example.com --workers 8 --output results.json\n```\n\n##### `websites` - Process Multiple Websites\n\nProcess images from multiple websites listed in a text file.\n\n```bash\n./generate-alt-text-cli websites \u003cfile\u003e [options]\n```\n\n**Arguments:**\n\n- `file` (required): Text file containing website URLs (one per line)\n\n**Options:**\n\n- `--workers`, `-w`: Number of parallel workers (default: configured max_workers)\n- `--output`, `-o`: Output file for results\n- `--format`, `-f`: Output format, choices: `json`, `excel` (default: json)\n\n**Examples:**\n\n```bash\n./generate-alt-text-cli websites website_urls.txt\n./generate-alt-text-cli websites sites.txt --output all_websites.xlsx --format excel\n./generate-alt-text-cli websites urls.txt --workers 4 --output combined_results.json\n```\n\n#### Global Options\n\nAll commands support the following patterns:\n\n- **Output formats**: Choose between JSON or Excel formats\n- **Parallel processing**: Adjust the number of worker threads for faster processing\n- **Context information**: Provide additional context to improve alt text quality\n\n## Project Architecture\n\nThe project is organized into several core modules:\n\n- **`_core/`**: Core functionality modules\n\n  - `cli_processor.py`: Parallel processing of multiple images or web pages\n  - `llm_processing.py`: AI-powered alt-text generation using OpenRouter\n  - `web_scraper.py`: Web page analysis and image extraction\n  - `exporter.py`: Export functionality (Excel, JSON)\n  - `models.py`: Data models for image information\n  - `config.py`: Configuration management\n  - `logger.py`: Logging utilities\n  - `prompts.py`: AI prompts for alt-text generation\n  - `utils.py`: Utility functions\n  - `app_info.py`: Configure UI text\n  - `sample_urls.py`: Configure example URLs\n  - `text_to_remove.py`: List of texts to remove from parsed content surrounding the image, e.g., text of navigational elements\n\n- **`_cli/`**: Command-line interface\n\n  - `cli.py`: Main CLI application\n\n- **`_tests/`**: Test suite\n- **`main.py`**: Streamlit web app\n- **`config.yaml`**: Application configuration\n- **`generate-alt-text-cli`**: Convenience script for CLI usage\n\n## Project Information\n\nThis tool was developed for the cantonal administration to help content creators generate accessible alt-texts for web content. It is designed to create drafts for German alt-texts that comply with web accessibility standards.\n\n## Project Team\n\n- **Simone Luchetta, Hannes Weber** - [Team Informationszugang \u0026 Dialog, Staatskanzlei](https://www.zh.ch/de/staatskanzlei/digitale-verwaltung/team.html)\n- **Céline Colombo** - [Koordinationsstelle Teilhabe, Statistisches Amt](https://www.zh.ch/de/politik-staat/teilhabe.html)\n- **Chantal Amrhein**, **Patrick Arnecke** – [Statistisches Amt Zürich, Team Data](https://www.zh.ch/de/direktion-der-justiz-und-des-innern/statistisches-amt/data.html)\n\nThanks to **Corinna Grobe**, **Thomas Hofer** and **Roger Zedi** for their valuable contributions.\n\n## Feedback and Contributing\n\nWe welcome feedback and contributions! [Email us](mailto:datashop@statistik.zh.ch) or open an issue or pull request.\n\n### Development Setup\n\nWe use [`ruff`](https://docs.astral.sh/ruff/) for linting and formatting.\n\nInstall pre-commit hooks for automatic checks before committing:\n\n```bash\npre-commit install\n```\n\n### Running Tests\n\n```bash\n# Run the test suite\nuv run python -m pytest\n\n# Run with coverage\nuv run python -m pytest --cov=_core\n```\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Disclaimer\n\nThis software incorporates AI models and has been developed according to and with the intent to be used under Swiss law. Please be aware that the EU Artificial Intelligence Act (EU AI Act) may, under certain circumstances, be applicable to your use of the software. You are solely responsible for ensuring that your use of the software as well as the underlying AI models complies with all applicable local, national and international laws and regulations. By using this software, you acknowledge and agree (a) that it is your responsibility to assess which laws and regulations, in particular regarding the use of AI technologies, are applicable to your intended use and to comply therewith, and (b) that you will hold us harmless from any action, claims, liability or loss in respect of your use of the software.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmachinelearningzh%2Falt-text-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmachinelearningzh%2Falt-text-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmachinelearningzh%2Falt-text-generator/lists"}