# PyArtifactory
[](https://github.com/anancarv/python-artifactory/actions)
[](https://badge.fury.io/py/pyartifactory)
[](https://www.codacy.com/gh/anancarv/python-artifactory/dashboard?utm_source=github.com&utm_medium=referral&utm_content=anancarv/python-artifactory&utm_campaign=Badge_Grade)
[](https://www.codacy.com/gh/anancarv/python-artifactory/dashboard?utm_source=github.com&utm_medium=referral&utm_content=anancarv/python-artifactory&utm_campaign=Badge_Coverage)

`pyartifactory` is a Python library to access the [Artifactory REST API](https://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API).
This library enables you to manage Artifactory resources such as users, groups, permissions, repositories, artifacts and access tokens in your applications. Based on Python 3.8+ type hints.
<!-- toc -->
- [Requirements](#requirements)
- [Install](#install)
- [Usage](#usage)
* [Authentication](#authentication)
+ [Basic authentication](#basic-authentication)
+ [Authentication with access token](#authentication-with-access-token)
* [SSL Cert Verification Options](#ssl-cert-verification-options)
* [Timeout option](#timeout-option)
* [Admin objects](#admin-objects)
+ [User](#user)
+ [Group](#group)
+ [Security](#security)
+ [Repository](#repository)
+ [Permission](#permission)
- [Artifactory lower than 6.6.0](#artifactory-lower-than-660)
- [Artifactory 6.6.0 or higher](#artifactory-660-or-higher)
* [Artifacts](#artifacts)
+ [Get the information about a file or folder](#get-the-information-about-a-file-or-folder)
+ [Deploy an artifact](#deploy-an-artifact)
+ [Deploy an artifact with properties](#deploy-an-artifact-with-properties)
+ [Deploy an artifact with checksums](#deploy-an-artifact-with-checksums)
+ [Download an artifact](#download-an-artifact)
+ [Retrieve artifact list](#retrieve-artifact-list)
+ [Retrieve artifact properties](#retrieve-artifact-properties)
+ [Set artifact properties](#set-artifact-properties)
+ [Update artifact properties](#update-artifact-properties)
+ [Retrieve artifact stats](#retrieve-artifact-stats)
+ [Copy artifact to a new location](#copy-artifact-to-a-new-location)
+ [Move artifact to a new location](#move-artifact-to-a-new-location)
+ [Delete an artifact](#delete-an-artifact)
* [Builds](#builds)
+ [Get a list of all builds](#get-a-list-of-all-builds)
+ [Get the information about a build](#get-the-information-about-a-build)
+ [Create build](#create-build)
+ [Promote a build](#promote-a-build)
+ [Delete one or more builds](#delete-one-or-more-builds)
+ [Rename a build](#rename-a-build)
+ [Get differences between two builds](#get-differences-between-two-builds)
* [Contributing](#contributing)
<!-- tocstop -->
## Requirements
- Python 3.8+
## Install
```python
pip install pyartifactory
```
## Usage
### Authentication
Since Artifactory 6.6.0 there is version 2 of the REST API for permission management, in case you have that version or higher, you need to pass api_version=2 to the constructor when you instantiate the class.
#### Basic authentication
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'), api_version=1)
```
#### Authentication with access token
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", access_token="your-access-token")
```
Note:
* If you set both `access_token` and `auth`, the access_token authentication will be chosen
* If you do not set any authentication method, API calls will be done without authentication (anonymous)
### SSL Cert Verification Options
Specify a local cert to use as client side certificate
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'), cert="/path_to_file/server.pem", api_version=1)
```
Specify a local cert to use as custom CA certificate
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'), verify="/path_to_file/ca.pem", cert="/path_to_file/server.pem", api_version=1)
```
> `verify` and `cert` configure certificates for distinct purposes. `verify` determines SSL/TLS certificate validation for the server, while `cert` supplies a client certificate for mutual authentication, as required by the server. You can use either one or both parameters as needed.
Disable host cert verification
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'), verify=False, api_version=1)
```
> `verify` can be also set as a boolean to enable/disable SSL host verification.
### Timeout option
Use timeout option to limit connect and read timeout in case the artifactory server is not responding in a timely manner.
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'), api_version=1, timeout=60)
```
> `timeout` is None by default.
### Admin objects
#### User
First, you need to create a new Artifactory object.
```python
from pyartifactory import Artifactory
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'))
```
Get the list of users:
```python
users = art.users.list()
```
Get a single user:
```python
user = art.users.get("test_user")
```
Create a user:
```python
from pyartifactory.models import NewUser
# Create User
user = NewUser(name="test_user", password="test_password", email="user@user.com")
new_user = art.users.create(user)
# Update user
user.email = "test@test.com"
updated_user = art.users.update(user)
```
Update a user:
```python
from pyartifactory.models import User
user = art.users.get("test_user")
# Update user
user.email = "test@test.com"
updated_user = art.users.update(user)
```
Delete a user:
```python
art.users.delete("test_user")
```
Unlock a user:
```python
art.users.unlock("test_user")
```
#### Group
Get the list of groups:
```python
groups = art.groups.list()
```
Get a single group:
```python
group = art.groups.get("group_name")
```
Create/Update a group:
```python
from pyartifactory.models import Group
# Create a Group
group = Group(name="test_group", description="test_group")
new_group = art.groups.create(group)
# Update a Group
group.description = "test_group_2"
updated_group = art.groups.update(group)
```
Delete a group:
```python
art.groups.delete("test_group")
```
#### Security
A set of methods for performing operations on apiKeys, passwords ...
```python
>>> art.security.
art.security.create_api_key( art.security.get_encrypted_password( art.security.revoke_api_key(
art.security.get_api_key( art.security.regenerate_api_key( art.security.revoke_user_api_key(
```
Create an access token:
```python
token = art.security.create_access_token(user_name='artifactory_user', refreshable=True, scope="applied-permissions/user")
```
Revoke an existing revocable token:
```python
art.security.revoke_access_token(token.access_token)
```
#### Repository
Get the list of repositories:
```python
repositories = art.repositories.list()
```
Get a single repository
```python
repo = art.repositories.get_repo("repo_name")
# According to the repo type, you'll have either a local, virtual or remote repository returned
```
Create/Update a repository:
```python
from pyartifactory.models import (
LocalRepository,
VirtualRepository,
RemoteRepository,
FederatedRepository
)
# Create local repo
local_repo = LocalRepository(key="test_local_repo")
new_local_repo = art.repositories.create_repo(local_repo)
# Create virtual repo
virtual_repo = VirtualRepository(key="test_virtual_repo")
new_virtual_repo = art.repositories.create_repo(virtual_repo)
# Create remote repo
remote_repo = RemoteRepository(key="test_remote_repo", url="http://test-url.com")
new_remote_repo = art.repositories.create_repo(remote_repo)
# Create federated repo
remote_repo = FederatedRepository(key="test_remote_repo")
new_federated_repo = art.repositories.create_repo(remote_repo)
# Update a repository
local_repo = art.repositories.get_repo("test_local_repo")
local_repo.description = "test_local_repo"
updated_local_repo = art.repositories.update_repo(local_repo)
```
Delete a repository:
```python
art.repositories.delete("test_local_repo")
```
#### Permission
Get the list of permissions:
```python
permissions = art.permissions.list()
```
Get a single permission:
```python
users = art.permissions.get("test_permission")
```
Create/Update a permission:
##### Artifactory lower than 6.6.0
```python
from pyartifactory.models import Permission
# Create a permission
permission = Permission(
**{
"name": "test_permission",
"repositories": ["test_repository"],
"principals": {
"users": {"test_user": ["r", "w", "n", "d"]},
"groups": {"developers": ["r"]},
},
}
)
perm = art.permissions.create(permission)
# Update permission
permission.repositories = ["test_repository_2"]
updated_permission = art.permissions.update(permission)
```
##### Artifactory 6.6.0 or higher
```python
from pyartifactory import Artifactory
from pyartifactory.models import PermissionV2
from pyartifactory.models.permission import PermissionEnumV2, PrincipalsPermissionV2, RepoV2, BuildV2, ReleaseBundleV2
# To use PermissionV2, make sure to set api_version=2
art = Artifactory(url="ARTIFACTORY_URL", auth=('USERNAME','PASSWORD_OR_API_KEY'), api_version=2)
# Create a permission
permission = PermissionV2(
name="test_permission",
repo=RepoV2(
repositories=["test_repository"],
actions=PrincipalsPermissionV2(
users={
"test_user": [
PermissionEnumV2.read,
PermissionEnumV2.annotate,
PermissionEnumV2.write,
PermissionEnumV2.delete,
]
},
groups={
"developers": [
PermissionEnumV2.read,
PermissionEnumV2.annotate,
PermissionEnumV2.write,
PermissionEnumV2.delete,
],
},
),
includePatterns=["**"],
excludePatterns=[],
),
build=BuildV2(
actions=PrincipalsPermissionV2(
users={
"test_user": [
PermissionEnumV2.read,
PermissionEnumV2.write,
]
},
groups={
"developers": [
PermissionEnumV2.read,
PermissionEnumV2.write,
],
},
),
includePatterns=[""],
excludePatterns=[""],
),
releaseBundle=ReleaseBundleV2(
repositories=["release-bundles"],
actions=PrincipalsPermissionV2(
users={
"test_user": [
PermissionEnumV2.read,
]
},
groups={
"developers": [
PermissionEnumV2.read,
],
},
),
includePatterns=[""],
excludePatterns=[""],
)
# You don't have to set all the objects repo, build and releaseBundle
# If you only need repo for example, you can set only the repo object
)
perm = art.permissions.create(permission)
# Update permission
permission.repo.repositories = ["test_repository_2"]
updated_permission = art.permissions.update(permission)
```
Delete a permission:
```python
art.permissions.delete("test_permission")
```
### Artifacts
#### Get the information about a file or folder
```python
artifact_info = art.artifacts.info("<ARTIFACT_PATH_IN_ARTIFACTORY>")
# file_info = art.artifacts.info("my-repository/my/artifact/directory/file.txt")
# folder_info = art.artifacts.info("my-repository/my/artifact/directory")
```
#### Deploy an artifact
```python
artifact = art.artifacts.deploy("<LOCAL_FILE_LOCATION>", "<ARTIFACT_PATH_IN_ARTIFACTORY>")
# artifact = art.artifacts.deploy("Desktop/myNewFile.txt", "my-repository/my/new/artifact/directory/file.txt")
```
#### Deploy an artifact with properties
```python
artifact = art.artifacts.deploy("<LOCAL_FILE_LOCATION>", "<ARTIFACT_PATH_IN_ARTIFACTORY>", "<PROPERTIES>")
# artifact = art.artifacts.deploy("Desktop/myNewFile.txt", "my-repository/my/new/artifact/directory/file.txt", {"retention": ["30"]})
```
#### Deploy an artifact with checksums
```python
artifact = art.artifacts.deploy("<LOCAL_FILE_LOCATION>", "<ARTIFACT_PATH_IN_ARTIFACTORY>", checksum_enabled=True)
# artifact = art.artifacts.deploy("Desktop/myNewFile.txt", "my-repository/my/new/artifact/directory/file.txt", checksums=True)
```
Deploy an artifact to the specified destination by checking if the artifact content already exists in Artifactory.
If Artifactory already contains a user-readable artifact with the same checksum the artifact content is copied over
to the new location and returns a response without requiring content transfer.
Otherwise, a 404 error is returned to indicate that content upload is expected in order to deploy the artifact.
**Note**: The performance might suffer when deploying artifacts with checksums enabled.
#### Download an artifact
```python
artifact = art.artifacts.download("<ARTIFACT_PATH_IN_ARTIFACTORY>", "<LOCAL_DIRECTORY_PATH>")
# artifact = art.artifacts.download("my-artifactory-repository/my/new/artifact/file.txt", "Desktop/my/local/directory")
# The artifact location is returned by the download method
# If you have not set a <LOCAL_DIRECTORY_PATH>, the artifact will be downloaded in the current directory
```
#### Retrieve artifact list
```python
artifacts = art.artifacts.list("<ARTIFACT_PATH_IN_ARTIFACTORY>")
# files_only = art.artifacts.list("<ARTIFACT_PATH_IN_ARTIFACTORY>", list_folders=False)
# non_recursive = art.artifacts.list("<ARTIFACT_PATH_IN_ARTIFACTORY>", recursive=False)
# max_depth = art.artifacts.list("<ARTIFACT_PATH_IN_ARTIFACTORY>", depth=3)
```
#### Retrieve artifact properties
```python
artifact_properties = art.artifacts.properties("<ARTIFACT_PATH_IN_ARTIFACTORY>") # returns all properties
# artifact_properties = art.artifacts.properties("my-repository/my/new/artifact/directory/file.txt")
artifact_properties = art.artifacts.properties("<ARTIFACT_PATH_IN_ARTIFACTORY>", ["prop1", "prop2"]) # returns specific properties
artifact_properties.properties["prop1"] # ["value1", "value1-bis"]
```
#### Set artifact properties
```python
artifact_properties = art.artifacts.set_properties("<ARTIFACT_PATH_IN_ARTIFACTORY>", {"prop1": ["value"], "prop2": ["value1", "value2", "etc"}) # recursive mode is enabled by default
artifact_properties = art.artifacts.set_properties("<ARTIFACT_PATH_IN_ARTIFACTORY>", {"prop1": ["value"], "prop2": ["value1", "value2", "etc"]}, False) # disable recursive mode
```
#### Update artifact properties
```python
artifact_properties = art.artifacts.update_properties("<ARTIFACT_PATH_IN_ARTIFACTORY>", {"prop1": ["value"], "prop2": ["value1", "value2", "etc"}) # recursive mode is enabled by default
artifact_properties = art.artifacts.update_properties("<ARTIFACT_PATH_IN_ARTIFACTORY>", {"prop1": ["value"], "prop2": ["value1", "value2", "etc"}, False) # disable recursive mode
```
#### Retrieve artifact stats
```python
artifact_stats = art.artifacts.stats("<ARTIFACT_PATH_IN_ARTIFACTORY>")
# artifact_stats = art.artifacts.stats("my-repository/my/new/artifact/directory/file.txt")
```
#### Copy artifact to a new location
```python
artifact = art.artifacts.copy("<CURRENT_ARTIFACT_PATH_IN_ARTIFACTORY>","<NEW_ARTIFACT_PATH_IN_ARTIFACTORY>")
# If you want to run a dryRun test, you can do the following:
# artifact = art.artifacts.copy("my-repository/current/artifact/path/file.txt","my-repository/new/artifact/path/file.txt", dryrun=True)
# It will return properties of the newly copied artifact
```
#### Move artifact to a new location
```python
artifact = art.artifacts.move("<CURRENT_ARTIFACT_PATH_IN_ARTIFACTORY>","<NEW_ARTIFACT_PATH_IN_ARTIFACTORY>")
# You can also run a dryRun test with the move operation
# It will return properties of the newly moved artifact
```
#### Delete an artifact
```python
art.artifacts.delete("<ARTIFACT_PATH_IN_ARTIFACTORY>")
```
### Builds
#### Get a list of all builds
```python
build_list: BuildListResponse = art.builds.list()
```
#### Get the information about a build
```python
build_info: BuildInfo = art.builds.get_build_info("<build_name>", "<build_number>")
```
Note: optional BuildProperties can be used to query the correct build info of interest.
```python
build_properties = BuildProperties(diff="<older_build>")
build_info: BuildInfo = art.builds.get_build_info("<build_name>", "<build_number>", properties=build_properties)
# build_info contains diff between <build_number> and <older_build>
```
```python
# started is the earliest build time to return
build_properties = BuildProperties(started="<yyyy-MM-dd'T'HH:mm:ss.SSSZ>")
build_info: BuildInfo = art.builds.get_build_info("<build_name>", "<build_number>", properties=build_properties)
```
#### Create build
```python
build_create_request = BuildCreateRequest(name="<build_name>", number="<build_number>", started="<Build start time in the format of yyyy-MM-dd'T'HH:mm:ss.SSSZ>")
create_build = art.builds.create_build(build_create_request)
```
#### Promote a build
```python
build_promote_request = BuildPromotionRequest(sourceRepo="<source-jfrog-repo>", targetRepo="<target-jfrog-repo>")
promote_build: BuildPromotionResult = art.builds.promote_build("<build_name>", "<build_number>", build_promote_request)
```
#### Delete one or more builds
```python
build_delete_request = BuildDeleteRequest(buildName="<build_name>", buildNumbers=["<build_number>", "<another_build_number>", ...])
art.builds.delete(build_delete_request)
```
#### Rename a build
```python
art.builds.build_rename("<build_name>", "<new_build_name>")
```
#### Get differences between two builds
```python
build_diffs: BuildDiffResponse = art.builds.build_diff("<build_name>", "<build_number>", "<older_build_number>")
```
### Contributing
Please read the [Development - Contributing](./CONTRIBUTING.md) guidelines.
Raw data
{
"_id": null,
"home_page": "https://github.com/anancarv/python-artifactory",
"name": "PyArtifactory",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "artifactory",
"author": "Ananias CARVALHO",
"author_email": "carvalhoananias@hotmail.com",
"download_url": "https://files.pythonhosted.org/packages/8c/99/c0e0fe657e44a78142831406537ba8f84ad07c9eb658d7e459015d263466/pyartifactory-2.7.1.tar.gz",
"platform": null,
"description": "# PyArtifactory\n\n[](https://github.com/anancarv/python-artifactory/actions)\n[](https://badge.fury.io/py/pyartifactory)\n[](https://www.codacy.com/gh/anancarv/python-artifactory/dashboard?utm_source=github.com&utm_medium=referral&utm_content=anancarv/python-artifactory&utm_campaign=Badge_Grade)\n[](https://www.codacy.com/gh/anancarv/python-artifactory/dashboard?utm_source=github.com&utm_medium=referral&utm_content=anancarv/python-artifactory&utm_campaign=Badge_Coverage)\n\n\n\n`pyartifactory` is a Python library to access the [Artifactory REST API](https://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API).\n\nThis library enables you to manage Artifactory resources such as users, groups, permissions, repositories, artifacts and access tokens in your applications. Based on Python 3.8+ type hints.\n\n<!-- toc -->\n\n- [Requirements](#requirements)\n- [Install](#install)\n- [Usage](#usage)\n * [Authentication](#authentication)\n + [Basic authentication](#basic-authentication)\n + [Authentication with access token](#authentication-with-access-token)\n * [SSL Cert Verification Options](#ssl-cert-verification-options)\n * [Timeout option](#timeout-option)\n * [Admin objects](#admin-objects)\n + [User](#user)\n + [Group](#group)\n + [Security](#security)\n + [Repository](#repository)\n + [Permission](#permission)\n - [Artifactory lower than 6.6.0](#artifactory-lower-than-660)\n - [Artifactory 6.6.0 or higher](#artifactory-660-or-higher)\n * [Artifacts](#artifacts)\n + [Get the information about a file or folder](#get-the-information-about-a-file-or-folder)\n + [Deploy an artifact](#deploy-an-artifact)\n + [Deploy an artifact with properties](#deploy-an-artifact-with-properties)\n + [Deploy an artifact with checksums](#deploy-an-artifact-with-checksums)\n + [Download an artifact](#download-an-artifact)\n + [Retrieve artifact list](#retrieve-artifact-list)\n + [Retrieve artifact properties](#retrieve-artifact-properties)\n + [Set artifact properties](#set-artifact-properties)\n + [Update artifact properties](#update-artifact-properties)\n + [Retrieve artifact stats](#retrieve-artifact-stats)\n + [Copy artifact to a new location](#copy-artifact-to-a-new-location)\n + [Move artifact to a new location](#move-artifact-to-a-new-location)\n + [Delete an artifact](#delete-an-artifact)\n * [Builds](#builds)\n + [Get a list of all builds](#get-a-list-of-all-builds)\n + [Get the information about a build](#get-the-information-about-a-build)\n + [Create build](#create-build)\n + [Promote a build](#promote-a-build)\n + [Delete one or more builds](#delete-one-or-more-builds)\n + [Rename a build](#rename-a-build)\n + [Get differences between two builds](#get-differences-between-two-builds)\n * [Contributing](#contributing)\n\n<!-- tocstop -->\n\n## Requirements\n\n- Python 3.8+\n\n## Install\n\n```python\npip install pyartifactory\n```\n\n## Usage\n\n### Authentication\n\nSince Artifactory 6.6.0 there is version 2 of the REST API for permission management, in case you have that version or higher, you need to pass api_version=2 to the constructor when you instantiate the class.\n\n#### Basic authentication\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'), api_version=1)\n```\n\n#### Authentication with access token\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", access_token=\"your-access-token\")\n```\n\nNote:\n* If you set both `access_token` and `auth`, the access_token authentication will be chosen\n* If you do not set any authentication method, API calls will be done without authentication (anonymous)\n\n### SSL Cert Verification Options\n\nSpecify a local cert to use as client side certificate\n\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'), cert=\"/path_to_file/server.pem\", api_version=1)\n```\n\nSpecify a local cert to use as custom CA certificate\n\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'), verify=\"/path_to_file/ca.pem\", cert=\"/path_to_file/server.pem\", api_version=1)\n```\n\n> `verify` and `cert` configure certificates for distinct purposes. `verify` determines SSL/TLS certificate validation for the server, while `cert` supplies a client certificate for mutual authentication, as required by the server. You can use either one or both parameters as needed.\n\nDisable host cert verification\n\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'), verify=False, api_version=1)\n```\n\n> `verify` can be also set as a boolean to enable/disable SSL host verification.\n\n### Timeout option\n\nUse timeout option to limit connect and read timeout in case the artifactory server is not responding in a timely manner.\n\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'), api_version=1, timeout=60)\n```\n\n> `timeout` is None by default.\n\n### Admin objects\n\n#### User\n\nFirst, you need to create a new Artifactory object.\n```python\nfrom pyartifactory import Artifactory\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'))\n```\n\nGet the list of users:\n```python\nusers = art.users.list()\n```\n\nGet a single user:\n```python\nuser = art.users.get(\"test_user\")\n```\n\nCreate a user:\n```python\nfrom pyartifactory.models import NewUser\n\n# Create User\nuser = NewUser(name=\"test_user\", password=\"test_password\", email=\"user@user.com\")\nnew_user = art.users.create(user)\n\n# Update user\nuser.email = \"test@test.com\"\nupdated_user = art.users.update(user)\n```\n\nUpdate a user:\n```python\nfrom pyartifactory.models import User\n\nuser = art.users.get(\"test_user\")\n\n# Update user\nuser.email = \"test@test.com\"\nupdated_user = art.users.update(user)\n```\n\nDelete a user:\n```python\nart.users.delete(\"test_user\")\n```\n\nUnlock a user:\n```python\nart.users.unlock(\"test_user\")\n```\n\n#### Group\n\nGet the list of groups:\n```python\ngroups = art.groups.list()\n```\n\nGet a single group:\n```python\ngroup = art.groups.get(\"group_name\")\n```\n\nCreate/Update a group:\n```python\nfrom pyartifactory.models import Group\n\n# Create a Group\ngroup = Group(name=\"test_group\", description=\"test_group\")\nnew_group = art.groups.create(group)\n\n# Update a Group\ngroup.description = \"test_group_2\"\nupdated_group = art.groups.update(group)\n```\n\nDelete a group:\n```python\nart.groups.delete(\"test_group\")\n```\n\n#### Security\n\nA set of methods for performing operations on apiKeys, passwords ...\n```python\n>>> art.security.\nart.security.create_api_key( art.security.get_encrypted_password( art.security.revoke_api_key(\nart.security.get_api_key( art.security.regenerate_api_key( art.security.revoke_user_api_key(\n```\n\nCreate an access token:\n```python\ntoken = art.security.create_access_token(user_name='artifactory_user', refreshable=True, scope=\"applied-permissions/user\")\n```\n\nRevoke an existing revocable token:\n```python\nart.security.revoke_access_token(token.access_token)\n```\n\n#### Repository\n\nGet the list of repositories:\n\n```python\nrepositories = art.repositories.list()\n```\n\nGet a single repository\n```python\nrepo = art.repositories.get_repo(\"repo_name\")\n# According to the repo type, you'll have either a local, virtual or remote repository returned\n```\n\nCreate/Update a repository:\n```python\nfrom pyartifactory.models import (\n LocalRepository,\n VirtualRepository,\n RemoteRepository,\n FederatedRepository\n)\n\n# Create local repo\nlocal_repo = LocalRepository(key=\"test_local_repo\")\nnew_local_repo = art.repositories.create_repo(local_repo)\n\n# Create virtual repo\nvirtual_repo = VirtualRepository(key=\"test_virtual_repo\")\nnew_virtual_repo = art.repositories.create_repo(virtual_repo)\n\n# Create remote repo\nremote_repo = RemoteRepository(key=\"test_remote_repo\", url=\"http://test-url.com\")\nnew_remote_repo = art.repositories.create_repo(remote_repo)\n\n# Create federated repo\nremote_repo = FederatedRepository(key=\"test_remote_repo\")\nnew_federated_repo = art.repositories.create_repo(remote_repo)\n\n# Update a repository\nlocal_repo = art.repositories.get_repo(\"test_local_repo\")\nlocal_repo.description = \"test_local_repo\"\nupdated_local_repo = art.repositories.update_repo(local_repo)\n```\n\nDelete a repository:\n```python\nart.repositories.delete(\"test_local_repo\")\n```\n\n#### Permission\nGet the list of permissions:\n\n```python\npermissions = art.permissions.list()\n```\n\nGet a single permission:\n```python\nusers = art.permissions.get(\"test_permission\")\n```\n\nCreate/Update a permission:\n\n##### Artifactory lower than 6.6.0\n\n```python\n\nfrom pyartifactory.models import Permission\n\n# Create a permission\npermission = Permission(\n **{\n \"name\": \"test_permission\",\n \"repositories\": [\"test_repository\"],\n \"principals\": {\n \"users\": {\"test_user\": [\"r\", \"w\", \"n\", \"d\"]},\n \"groups\": {\"developers\": [\"r\"]},\n },\n }\n)\nperm = art.permissions.create(permission)\n\n# Update permission\npermission.repositories = [\"test_repository_2\"]\nupdated_permission = art.permissions.update(permission)\n```\n\n##### Artifactory 6.6.0 or higher\n```python\nfrom pyartifactory import Artifactory\nfrom pyartifactory.models import PermissionV2\nfrom pyartifactory.models.permission import PermissionEnumV2, PrincipalsPermissionV2, RepoV2, BuildV2, ReleaseBundleV2\n\n# To use PermissionV2, make sure to set api_version=2\nart = Artifactory(url=\"ARTIFACTORY_URL\", auth=('USERNAME','PASSWORD_OR_API_KEY'), api_version=2)\n\n# Create a permission\npermission = PermissionV2(\n name=\"test_permission\",\n repo=RepoV2(\n repositories=[\"test_repository\"],\n actions=PrincipalsPermissionV2(\n users={\n \"test_user\": [\n PermissionEnumV2.read,\n PermissionEnumV2.annotate,\n PermissionEnumV2.write,\n PermissionEnumV2.delete,\n ]\n },\n groups={\n \"developers\": [\n PermissionEnumV2.read,\n PermissionEnumV2.annotate,\n PermissionEnumV2.write,\n PermissionEnumV2.delete,\n ],\n },\n ),\n includePatterns=[\"**\"],\n excludePatterns=[],\n ),\n build=BuildV2(\n actions=PrincipalsPermissionV2(\n users={\n \"test_user\": [\n PermissionEnumV2.read,\n PermissionEnumV2.write,\n ]\n },\n groups={\n \"developers\": [\n PermissionEnumV2.read,\n PermissionEnumV2.write,\n ],\n },\n ),\n includePatterns=[\"\"],\n excludePatterns=[\"\"],\n ),\n releaseBundle=ReleaseBundleV2(\n repositories=[\"release-bundles\"],\n actions=PrincipalsPermissionV2(\n users={\n \"test_user\": [\n PermissionEnumV2.read,\n ]\n },\n groups={\n \"developers\": [\n PermissionEnumV2.read,\n ],\n },\n ),\n includePatterns=[\"\"],\n excludePatterns=[\"\"],\n )\n # You don't have to set all the objects repo, build and releaseBundle\n # If you only need repo for example, you can set only the repo object\n)\nperm = art.permissions.create(permission)\n\n# Update permission\npermission.repo.repositories = [\"test_repository_2\"]\nupdated_permission = art.permissions.update(permission)\n```\n\nDelete a permission:\n```python\nart.permissions.delete(\"test_permission\")\n```\n\n### Artifacts\n\n#### Get the information about a file or folder\n```python\nartifact_info = art.artifacts.info(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\")\n# file_info = art.artifacts.info(\"my-repository/my/artifact/directory/file.txt\")\n# folder_info = art.artifacts.info(\"my-repository/my/artifact/directory\")\n```\n\n#### Deploy an artifact\n\n```python\nartifact = art.artifacts.deploy(\"<LOCAL_FILE_LOCATION>\", \"<ARTIFACT_PATH_IN_ARTIFACTORY>\")\n# artifact = art.artifacts.deploy(\"Desktop/myNewFile.txt\", \"my-repository/my/new/artifact/directory/file.txt\")\n```\n\n#### Deploy an artifact with properties\n\n```python\nartifact = art.artifacts.deploy(\"<LOCAL_FILE_LOCATION>\", \"<ARTIFACT_PATH_IN_ARTIFACTORY>\", \"<PROPERTIES>\")\n# artifact = art.artifacts.deploy(\"Desktop/myNewFile.txt\", \"my-repository/my/new/artifact/directory/file.txt\", {\"retention\": [\"30\"]})\n```\n\n#### Deploy an artifact with checksums\n\n```python\nartifact = art.artifacts.deploy(\"<LOCAL_FILE_LOCATION>\", \"<ARTIFACT_PATH_IN_ARTIFACTORY>\", checksum_enabled=True)\n# artifact = art.artifacts.deploy(\"Desktop/myNewFile.txt\", \"my-repository/my/new/artifact/directory/file.txt\", checksums=True)\n```\nDeploy an artifact to the specified destination by checking if the artifact content already exists in Artifactory.\n\nIf Artifactory already contains a user-readable artifact with the same checksum the artifact content is copied over\nto the new location and returns a response without requiring content transfer.\n\nOtherwise, a 404 error is returned to indicate that content upload is expected in order to deploy the artifact.\n\n**Note**: The performance might suffer when deploying artifacts with checksums enabled.\n\n#### Download an artifact\n```python\nartifact = art.artifacts.download(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", \"<LOCAL_DIRECTORY_PATH>\")\n# artifact = art.artifacts.download(\"my-artifactory-repository/my/new/artifact/file.txt\", \"Desktop/my/local/directory\")\n# The artifact location is returned by the download method\n# If you have not set a <LOCAL_DIRECTORY_PATH>, the artifact will be downloaded in the current directory\n```\n\n#### Retrieve artifact list\n```python\nartifacts = art.artifacts.list(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\")\n# files_only = art.artifacts.list(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", list_folders=False)\n# non_recursive = art.artifacts.list(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", recursive=False)\n# max_depth = art.artifacts.list(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", depth=3)\n```\n\n#### Retrieve artifact properties\n```python\nartifact_properties = art.artifacts.properties(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\") # returns all properties\n# artifact_properties = art.artifacts.properties(\"my-repository/my/new/artifact/directory/file.txt\")\nartifact_properties = art.artifacts.properties(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", [\"prop1\", \"prop2\"]) # returns specific properties\nartifact_properties.properties[\"prop1\"] # [\"value1\", \"value1-bis\"]\n```\n\n#### Set artifact properties\n```python\nartifact_properties = art.artifacts.set_properties(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", {\"prop1\": [\"value\"], \"prop2\": [\"value1\", \"value2\", \"etc\"}) # recursive mode is enabled by default\nartifact_properties = art.artifacts.set_properties(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", {\"prop1\": [\"value\"], \"prop2\": [\"value1\", \"value2\", \"etc\"]}, False) # disable recursive mode\n```\n\n#### Update artifact properties\n```python\nartifact_properties = art.artifacts.update_properties(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", {\"prop1\": [\"value\"], \"prop2\": [\"value1\", \"value2\", \"etc\"}) # recursive mode is enabled by default\nartifact_properties = art.artifacts.update_properties(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\", {\"prop1\": [\"value\"], \"prop2\": [\"value1\", \"value2\", \"etc\"}, False) # disable recursive mode\n```\n\n#### Retrieve artifact stats\n```python\nartifact_stats = art.artifacts.stats(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\")\n# artifact_stats = art.artifacts.stats(\"my-repository/my/new/artifact/directory/file.txt\")\n```\n\n#### Copy artifact to a new location\n```python\nartifact = art.artifacts.copy(\"<CURRENT_ARTIFACT_PATH_IN_ARTIFACTORY>\",\"<NEW_ARTIFACT_PATH_IN_ARTIFACTORY>\")\n\n# If you want to run a dryRun test, you can do the following:\n# artifact = art.artifacts.copy(\"my-repository/current/artifact/path/file.txt\",\"my-repository/new/artifact/path/file.txt\", dryrun=True)\n# It will return properties of the newly copied artifact\n```\n\n#### Move artifact to a new location\n```python\nartifact = art.artifacts.move(\"<CURRENT_ARTIFACT_PATH_IN_ARTIFACTORY>\",\"<NEW_ARTIFACT_PATH_IN_ARTIFACTORY>\")\n\n# You can also run a dryRun test with the move operation\n# It will return properties of the newly moved artifact\n```\n\n#### Delete an artifact\n```python\nart.artifacts.delete(\"<ARTIFACT_PATH_IN_ARTIFACTORY>\")\n```\n\n\n\n### Builds\n\n#### Get a list of all builds\n```python\nbuild_list: BuildListResponse = art.builds.list()\n```\n\n#### Get the information about a build\n\n```python\nbuild_info: BuildInfo = art.builds.get_build_info(\"<build_name>\", \"<build_number>\")\n```\n\nNote: optional BuildProperties can be used to query the correct build info of interest.\n\n```python\nbuild_properties = BuildProperties(diff=\"<older_build>\")\nbuild_info: BuildInfo = art.builds.get_build_info(\"<build_name>\", \"<build_number>\", properties=build_properties)\n# build_info contains diff between <build_number> and <older_build>\n```\n\n\n```python\n# started is the earliest build time to return\nbuild_properties = BuildProperties(started=\"<yyyy-MM-dd'T'HH:mm:ss.SSSZ>\")\nbuild_info: BuildInfo = art.builds.get_build_info(\"<build_name>\", \"<build_number>\", properties=build_properties)\n```\n\n#### Create build\n\n```python\nbuild_create_request = BuildCreateRequest(name=\"<build_name>\", number=\"<build_number>\", started=\"<Build start time in the format of yyyy-MM-dd'T'HH:mm:ss.SSSZ>\")\ncreate_build = art.builds.create_build(build_create_request)\n```\n\n\n#### Promote a build\n```python\nbuild_promote_request = BuildPromotionRequest(sourceRepo=\"<source-jfrog-repo>\", targetRepo=\"<target-jfrog-repo>\")\npromote_build: BuildPromotionResult = art.builds.promote_build(\"<build_name>\", \"<build_number>\", build_promote_request)\n```\n\n#### Delete one or more builds\n```python\nbuild_delete_request = BuildDeleteRequest(buildName=\"<build_name>\", buildNumbers=[\"<build_number>\", \"<another_build_number>\", ...])\nart.builds.delete(build_delete_request)\n```\n\n#### Rename a build\n```python\nart.builds.build_rename(\"<build_name>\", \"<new_build_name>\")\n```\n\n#### Get differences between two builds\n```python\nbuild_diffs: BuildDiffResponse = art.builds.build_diff(\"<build_name>\", \"<build_number>\", \"<older_build_number>\")\n```\n\n\n### Contributing\nPlease read the [Development - Contributing](./CONTRIBUTING.md) guidelines.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Typed interactions with the Jfrog Artifactory REST API",
"version": "2.7.1",
"project_urls": {
"Bug Tracker": "https://github.com/anancarv/python-artifactory/issues",
"Documentation": "https://github.com/anancarv/python-artifactory",
"Homepage": "https://github.com/anancarv/python-artifactory",
"Repository": "https://github.com/anancarv/python-artifactory"
},
"split_keywords": [
"artifactory"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d466a6eb5e0c51e31b669d6a8bc4a9a15dfe6629e87f301c6d1b230a258697f2",
"md5": "b5dfb70362401b094fd95926b0501a5a",
"sha256": "d29bfba5ded72f10b62e43c221ea77ee795ada70debb9c4514d5b288e10a39e7"
},
"downloads": -1,
"filename": "pyartifactory-2.7.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b5dfb70362401b094fd95926b0501a5a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 30788,
"upload_time": "2024-09-23T21:28:42",
"upload_time_iso_8601": "2024-09-23T21:28:42.952625Z",
"url": "https://files.pythonhosted.org/packages/d4/66/a6eb5e0c51e31b669d6a8bc4a9a15dfe6629e87f301c6d1b230a258697f2/pyartifactory-2.7.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8c99c0e0fe657e44a78142831406537ba8f84ad07c9eb658d7e459015d263466",
"md5": "e6d06343702795096c08bc5296abd152",
"sha256": "2904f03ca34d1f738e35d2d2976e696337b3a52cd83d37d777d0b61363b5c038"
},
"downloads": -1,
"filename": "pyartifactory-2.7.1.tar.gz",
"has_sig": false,
"md5_digest": "e6d06343702795096c08bc5296abd152",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 27937,
"upload_time": "2024-09-23T21:28:44",
"upload_time_iso_8601": "2024-09-23T21:28:44.655442Z",
"url": "https://files.pythonhosted.org/packages/8c/99/c0e0fe657e44a78142831406537ba8f84ad07c9eb658d7e459015d263466/pyartifactory-2.7.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-23 21:28:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "anancarv",
"github_project": "python-artifactory",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pyartifactory"
}