{"id":23663747,"url":"https://github.com/tahv/pyforce","last_synced_at":"2025-08-01T05:35:39.138Z","repository":{"id":230565767,"uuid":"779673326","full_name":"tahv/pyforce","owner":"tahv","description":"Python wrapper for Perforce p4 command-line client","archived":false,"fork":false,"pushed_at":"2024-03-31T16:21:02.000Z","size":46,"stargazers_count":17,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-02T16:18:02.607Z","etag":null,"topics":["p4","perforce","python"],"latest_commit_sha":null,"homepage":"https://pyforce.readthedocs.io","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/tahv.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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}},"created_at":"2024-03-30T13:36:29.000Z","updated_at":"2025-02-20T15:51:54.000Z","dependencies_parsed_at":"2024-12-29T05:33:10.721Z","dependency_job_id":"3a2eb211-64d0-44fc-9f3e-640386454e62","html_url":"https://github.com/tahv/pyforce","commit_stats":null,"previous_names":["tahv/pyforce"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/tahv/pyforce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tahv%2Fpyforce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tahv%2Fpyforce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tahv%2Fpyforce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tahv%2Fpyforce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tahv","download_url":"https://codeload.github.com/tahv/pyforce/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tahv%2Fpyforce/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266625265,"owners_count":23958305,"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-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":["p4","perforce","python"],"created_at":"2024-12-29T05:33:03.669Z","updated_at":"2025-07-23T05:37:50.605Z","avatar_url":"https://github.com/tahv.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pyforce\n\n[![License - MIT][license-badge]][pyforce-license]\n[![PyPI - Python Version][python-version-badge]][pyforce-pypi]\n[![PyPI - Version][version-badge]][pyforce-pypi]\n[![Linter - Ruff][ruff-badge]][ruff-repo]\n[![Types - Mypy][mypy-badge]][mypy-repo]\n[![CI - Tests][pyforce-workflow-tests-badge]][pyforce-workflow-tests]\n[![Documentation Status][pyforce-docs-badge]][pyforce-documentation]\n\nPython wrapper for Perforce p4 command-line client.\n\n## Features\n\n- Python wrapper for the `p4` command using [marshal](https://docs.python.org/3/library/marshal.html).\n- Built with [Pydantic](https://github.com/pydantic/pydantic).\n- Fully typed.\n- Built for scripting.\n\n## Installation\n\n```bash\npython -m pip install pyforce-p4\n```\n\n## Quickstart\n\n```python\nimport pyforce\n\nconnection = pyforce.Connection(host=\"localhost:1666\", user=\"foo\", client=\"my-client\")\n\n# Create a new file in our client\nfile = \"/home/foo/my-client/bar.txt\"\nfp = open(file, \"w\")\nfp.write(\"bar\")\nfp.close()\n\n# Run 'p4 add', open our file for addition to the depot\n_, infos = pyforce.add(connection, [file])\nprint(infos[0])\n\"\"\"\nActionInfo(\n    action='add', \n    client_file='/home/foo/my-client/bar.txt', \n    depot_file='//my-depot/my-stream/bar.txt', \n    file_type='text', \n    work_rev=1\n)\n\"\"\"\n\n# Run 'p4 submit', submitting our local file\npyforce.p4(connection, [\"submit\", \"-d\", \"Added bar.txt\", file])\n\n# Run 'p4 fstat', listing all files in depot\nfstats = list(pyforce.fstat(connection, [\"//...\"]))\nprint(fstats[0])\n\"\"\"\nFStat(\n    client_file='/home/foo/my-client/bar.txt', \n    depot_file='//my-depot/my-stream/bar.txt', \n    head=HeadInfo(\n        action=\u003cAction.ADD: 'add'\u003e, \n        change=2, \n        revision=1, \n        file_type='text', \n        time=datetime.datetime(2024, 3, 29, 13, 56, 57, tzinfo=datetime.timezone.utc), \n        mod_time=datetime.datetime(2024, 3, 29, 13, 56, 11, tzinfo=datetime.timezone.utc)\n    ), \n    have_rev=1, \n    is_mapped=True, \n    others_open=None\n)\n\"\"\"\n```\n\nPyforce has functions for the most common `p4` commands\nbut can execute more complexe commands with `pyforce.p4`.\n\nFor example, pyforce doesn't have a function to create a new client workspace,\nhere is how to create one using `pyforce.p4`.\n\n```python\nimport pyforce\n\nconnection = pyforce.Connection(port=\"localhost:1666\", user=\"foo\")\n\n# Create client\ncommand = [\"client\", \"-o\", \"-S\", \"//my-depot/my-stream\", \"my-client\"]\ndata = pyforce.p4(connection, command)[0]\ndata[\"Root\"] = \"/home/foo/my-client\"\npyforce.p4(connection, [\"client\", \"-i\"], stdin=data)\n\n# Get created client\nclient = pyforce.get_client(connection,  \"my-client\")\nprint(client)\n\"\"\"\nClient(\n    name='my-client', \n    host='5bb1735f73fc', \n    owner='foo', \n    root=PosixPath('/home/foo/my-client'), \n    stream='//my-depot/my-stream', \n    type=\u003cClientType.STANDARD: 'writeable'\u003e, \n    views=[View(left='//my-depot/my-stream/...', right='//my-client/...')]\n)\n\"\"\"\n```\n\n## Documentation\n\nSee pyforce [documentation](https://pyforce.readthedocs.io/latest) for more details.\n\n## Contributing\n\nFor guidance on setting up a development environment and contributing to pyforce,\nsee the [Contributing](https://pyforce.readthedocs.io/latest/contributing.html) section.\n\n\u003c!-- Links --\u003e\n\n[license-badge]: https://img.shields.io/github/license/tahv/pyforce?label=License\n[ruff-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json\n[version-badge]: https://img.shields.io/pypi/v/pyforce-p4?logo=pypi\u0026label=PyPI\u0026logoColor=white\n[python-version-badge]: https://img.shields.io/pypi/pyversions/pyforce-p4?logo=python\u0026label=Python\u0026logoColor=white\n[mypy-badge]: https://img.shields.io/badge/Types-Mypy-blue.svg\n[pyforce-workflow-tests-badge]: https://github.com/tahv/pyforce/actions/workflows/tests.yml/badge.svg\n[pyforce-docs-badge]: https://readthedocs.org/projects/pyforce/badge/?version=latest\n\n[pyforce-license]: https://github.com/tahv/pyforce/blob/main/LICENSE\n[ruff-repo]: https://github.com/astral-sh/ruff\n[pyforce-pypi]: https://pypi.org/project/pyforce-p4\n[mypy-repo]: https://github.com/python/mypy\n[pyforce-workflow-tests]: https://github.com/tahv/pyforce/actions/workflows/tests.yml\n[pyforce-documentation]: https://pyforce.readthedocs.io/latest\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftahv%2Fpyforce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftahv%2Fpyforce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftahv%2Fpyforce/lists"}