{"id":31721286,"url":"https://github.com/cumulus13/pypihub_flask","last_synced_at":"2026-01-20T16:45:04.145Z","repository":{"id":297179630,"uuid":"995876338","full_name":"cumulus13/pypihub_flask","owner":"cumulus13","description":"a simple fast local PyPI server with caching and package upload capabilities","archived":false,"fork":false,"pushed_at":"2025-08-11T13:43:32.000Z","size":36,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-25T12:42:09.364Z","etag":null,"topics":["caching","local","pypi","pypi-server","python","repository","serve","server"],"latest_commit_sha":null,"homepage":"https://github.com/cumulus13/pypihub_flask","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cumulus13.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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-06-04T06:19:10.000Z","updated_at":"2025-08-11T13:43:28.000Z","dependencies_parsed_at":"2025-06-08T05:15:46.615Z","dependency_job_id":null,"html_url":"https://github.com/cumulus13/pypihub_flask","commit_stats":null,"previous_names":["cumulus13/pypihub_flask"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/cumulus13/pypihub_flask","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cumulus13%2Fpypihub_flask","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cumulus13%2Fpypihub_flask/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cumulus13%2Fpypihub_flask/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cumulus13%2Fpypihub_flask/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cumulus13","download_url":"https://codeload.github.com/cumulus13/pypihub_flask/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cumulus13%2Fpypihub_flask/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000703,"owners_count":26082911,"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-10-09T02:00:07.460Z","response_time":59,"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":["caching","local","pypi","pypi-server","python","repository","serve","server"],"created_at":"2025-10-09T03:46:09.642Z","updated_at":"2026-01-20T16:45:04.140Z","avatar_url":"https://github.com/cumulus13.png","language":"Python","funding_links":["https://www.buymeacoffee.com/cumulus13","https://ko-fi.com/cumulus13","https://www.patreon.com/cumulus13"],"categories":[],"sub_categories":[],"readme":"# PyPihub - Local PyPI Server\n\nPyPihub is a simple local PyPI server with caching and package upload capabilities. This server allows you to host your Python packages locally, cache packages from the official PyPI, and supports package uploads via `twine`.\n\nThis version uses Flask. If you install via pip, use: `pip install pypihub[flask]`\n\nWhen installing with pip, PyPihub will not interrupt the download or installation process. If the requested package is not found in the `cache` or `package` directory, PyPihub will fetch it directly from pypi.org and simultaneously serve it to the client. This means the client does not have to wait for the server to finish downloading before receiving the package. All downloaded packages from pypi.org will also be saved to the cache for future use.\n\n## Key Features\n\n- **Multi-platform**: Supports any platform (Linux, Windows, Mac, etc.)\n- **Local Package Hosting**: Host your own Python packages locally\n- **PyPI Caching**: Automatic caching of packages from official PyPI for faster access\n- **Twine Support**: Upload packages using `twine` with authentication\n- **Web Interface**: Simple web interface for browsing packages\n- **Flexible Configuration**: Configuration via INI files, environment variables, or command arguments\n\n## Installation\n\n### Requirements\n\n```bash\npip install flask beautifulsoup4 requests pydebugger configset rich rich-argparse pathlib\n```\n\n### Download and Setup\n\n```bash\ngit clone \u003crepository-url\u003e\ncd pypihub\n```\n\nOr you can install with pip:\n```bash\n$ pip install pypihub[flask]\n```\n\n## Configuration\n\n### 1. Configuration File (pypihub.ini)\n\nCreate a `pypihub.ini` as an alternative config file, or it will be created automatically in the same directory as `pypihub.py`:\n\n```ini\n[dirs]\nbase = /path/to/base/directory\nlocal_pkg = /path/to/local/packages\ncache = /path/to/cache\n\n[urls]\npypi_simple = https://pypi.org/simple\n\n[server]\nhost = 0.0.0.0\nport = 5000\n\n[auths]\nusers = pypihub,pypihub;user2,pass2\n```\n\n### 2. Settings File (settings.py)\n\nAlternatively, create a `settings.py` file (see example below):\n\n```python\nBASE_DIR = \"/path/to/base\"\nLOCAL_PKG_DIR = \"/path/to/packages\"\nCACHE_DIR = \"/path/to/cache\"\nPYPI_SIMPLE_URL = \"https://pypi.org/simple\"\nHOST = \"0.0.0.0\"\nPORT = 5000\nAUTHS = [(\"pypihub\", \"pypihub\"), (\"user2\", \"pass2\")]\nCONFIGFILE = \"pypihub.ini\"\n```\n\n### 3. Environment Variables\n\n```bash\nexport BASE_DIR=\"/path/to/base\"\nexport LOCAL_PKG_DIR=\"/path/to/packages\"\nexport CACHE_DIR=\"/path/to/cache\"\nexport PYPI_SIMPLE_URL=\"https://pypi.org/simple\"\nexport HOST=\"0.0.0.0\"\nexport PORT=\"5000\"\nexport CONFIGFILE=\"pypihub.ini\"\n```\n\n## Usage\n\n### Running the Server\n\n```bash\n# Using default settings\npython pypihub.py\n\n# With custom configuration\n# Option: '-c /path/to/config.ini'\npython pypihub.py -c /path/to/config.ini -H 127.0.0.1 -P 8080\n\n# Verbose mode\npython pypihub.py -v\n\n# Show help\npython pypihub.py -h\n```\n\n### Command Line Arguments\n\n```\n-c, --config          Path to configuration file\n-b, --base-dir        Base directory for server\n-l, --local-pkg-dir   Directory for local packages\n-C, --cache-dir       Directory for cached packages\n-p, --pypi-simple-url PyPI simple index URL\n-H, --host            Host to run server on\n-P, --port            Port to run server on\n-V, --version         Show PyPihub version\n-v, --verbose         Enable verbose output\n```\n\n## Package Upload\n\n### Using Twine\n\n1. **Configure ~/.pypirc**:\n\n```ini\n[distutils]\nindex-servers = pypihub\n\n[pypihub]\nrepository = http://localhost:5000/\nusername = pypihub\npassword = pypihub\n```\n\n2. **Upload package**:\n\n```bash\n# Build package first\npython setup.py sdist bdist_wheel\n\n# Upload to pypihub\ntwine upload --repository pypihub dist/*\n```\n\n### Manual Upload via HTTP\n\n```bash\ncurl -X POST \\\n  -u pypihub:pypihub \\\n  -F \"file=@package-1.0.0-py3-none-any.whl\" \\\n  http://localhost:5000/upload/package-name/\n```\n\n## Installing Packages from PyPihub\n\n### Configure pip\n\nAdd to `~/.pip/pip.conf` (Linux/Mac) or `%APPDATA%\\pip\\pip.ini` (Windows):\n\n```ini\n[global]\nextra-index-url = http://localhost:5000/simple/\ntrusted-host = localhost\n```\n\n### Install Package\n\n```bash\n# Install from pypihub (with fallback to PyPI)\npip install package-name\n\n# Install only from pypihub\npip install --index-url http://localhost:5000/simple/ package-name\n\n# Install with extra index\npip install --extra-index-url http://localhost:5000/simple/ package-name\n```\n\n## API Endpoints\n\n### Web Interface\n- `GET /` - Main page with list of local packages\n\n### Package Management\n- `POST /upload/\u003cpackage\u003e/` - Upload package (with auth)\n- `POST /upload/` - Upload package via twine (with auth)\n- `GET /packages/\u003cpackage\u003e/\u003cfilename\u003e` - Serve local package files\n- `GET /cache/\u003cpackage\u003e/\u003cfilename\u003e` - Serve cached package files\n\n### Package Index\n- `GET /simple/\u003cpackage\u003e/` - Simple index for specific package\n\n## Directory Structure\n\n```\npypihub/\n├── pypihub.py              # Main application\n├── pypihub.ini             # Configuration file (optional)\n├── settings.py           # Settings file (optional)\n├── packages/             # Local packages directory\n│   └── package-name/\n│       ├── package-1.0.0.tar.gz\n│       └── package-1.0.0-py3-none-any.whl\n├── cache/                # Cached packages from PyPI\n│   └── requests/\n│       └── requests-2.28.1-py3-none-any.whl\n└── logs/                 # Log files (if configured)\n```\n\n## Authentication\n\nDefault credentials:\n- Username: `pypihub`\n- Password: `pypihub`\n\n`Change the default credentials before using in production.`\n\nTo change credentials, edit configuration in `settings.py`, `pypihub.ini`, or environment variables.\n\nexample 'pypihub.ini' for authentication\n\n```ini\n[auths]\nusers = userame password\n```\n\n## Logging\n\nPyPihub uses custom logging with levels:\n- EMERGENCY\n- CRITICAL\n- ERROR\n- WARNING\n- NOTICE\n- INFO\n- DEBUG\n\nSet `verbose` mode with `-v` for debug logging.\n\n## Troubleshooting\n\n### Package not found\n- Ensure package exists in local directory or is available on PyPI\n- Check `PYPI_SIMPLE_URL` configuration\n\n### Upload failed\n- Check authentication credentials\n- Ensure `LOCAL_PKG_DIR` directory is writable\n- Check if file already exists (409 error)\n\n### Cache not working\n- Ensure `CACHE_DIR` directory is writable\n- Check internet connection for downloading from PyPI\n\n### Port already in use\n- Change port with `-P` parameter or configuration\n- Check processes using port: `lsof -i :5000`\n\n## Development\n\n### Dependencies\n- Flask - Web framework\n- BeautifulSoup4 - HTML parsing\n- Requests - HTTP client\n- Rich - Console output formatting\n- ConfigSet - Configuration management\n- PyDebugger - Debug utilities\n\n### Contributing\n1. Fork repository\n2. Create feature branch\n3. Commit changes\n4. Push to branch\n5. Create Pull Request\n6. Describe your changes in the Pull Request.\n\n## License\n\nPyPihub is released under the [GNU Lesser General Public License v3.0 (LGPL-3.0)](https://www.gnu.org/licenses/lgpl-3.0.html).\n\nYou should have received a copy of the GNU Lesser General Public License along with this program.  \nIf not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/).\n\nFor commercial licensing options, please contact: [cumulus13@gmail.com](mailto:cumulus13@gmail.com)\n\n## Support\n\nFor issues and questions, please create/open an issue in the repository or contact [cumulus13@gmail.com](mailto:cumulus13@gmail.com).\n\n---\n\n**PyPihub** - Simplifying local Python package management\n\n`Warning: Do not expose this server to the public internet without proper authentication and security measures.`\n\n## Author\n[Hadi Cahyadi](mailto:cumulus13@gmail.com)\n    \n[![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/cumulus13)\n\n[![Donate via Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/cumulus13)\n\n[Support me on Patreon](https://www.patreon.com/cumulus13)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcumulus13%2Fpypihub_flask","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcumulus13%2Fpypihub_flask","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcumulus13%2Fpypihub_flask/lists"}