# dcrx
[![PyPI version](https://img.shields.io/pypi/v/dcrx?color=gre)](https://pypi.org/project/dcrx/)
[![License](https://img.shields.io/github/license/scorbettUM/dcrx)](https://github.com/scorbettUM/dcrx/blob/main/LICENSE)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/scorbettUM/dcrx/blob/main/CODE_OF_CONDUCT.md)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dcrx)](https://pypi.org/project/dcrx/)
DockerX (dcrx) is a library for creating Docker images via an SQL query-builder like API. It is designed to facilitate programmatic, typesafe, and in-memory image generation. dcrx is *not* a wrapper around the Docker CLI or API, nor is it an implementation of these things. Rather, it is designed a lightweight, single-dependency means of writing and creating images that can then be provided to the Docker CLI or SDK for consumption.
# Setup and Install
dcrx is available via PyPi as an installable package. We recommend using Python 3.10+ and a virtual environment. To install dcrx, run:
```bash
python -m venv ~/.dcrx && \
source ~/.dcrx/bin/activate && \
pip install dcrx
```
# Getting Started
dcrx uses a combination of method chaining common to SQL query builder libraries with Pydantic type validation to help you build images with fewer mistakes. As an example, let's create a basic Docker image that echoes "Hello world!" to output upon running the Docker image.
First let's create an empty Python file:
```
touch hello_world.py
```
Open the file and import `Image` from `dcrx`:
```python
from dcrx import Image
```
The Image class is the primary and only interface for generating and working with Docker images in dcrx. Let's go ahead and create an instance:
```python
from dcrx import Image
hello_world = Image("hello-world")
```
Note that we need to provide the name of the image to our class. We can also provide a tag via the `tag` keyword argument if needed (the default is `latest`):
```python
from dcrx import Image
hello_world = Image("hello-world", tag="latest")
```
Next let's call the `stage()` method on our `hello_world` Image instance, passing both the base image name and image tag from which we want to create our image. We'll use `python` as our base image and `3.11-slim` as our tag:
```python
from dcrx import Image
hello_world = Image("hello-world", tag="latest")
hello_world.stage(
"python",
"3.11-slim"
)
```
This call translates directly to:
```
FROM python:3.11-slim
```
underneath, just as if you were writing it in the image yourself! You can also use the optional `alias` arg to name the stage:
```python
from dcrx import Image
hello_world = Image("hello-world", tag="latest")
hello_world.stage(
"python",
"3.11-slim",
alias="build"
)
```
which translates to:
```
FROM python:3.11-slim as build
```
This is particularly useful for multi-stage builds.
Next let's chain a call to the `entrypoint()` method, passing a list consisting of the CLI command (`echo` in this instance) and positional or keyword arguments/values we want to use:
```python
from dcrx import Image
hello_world = Image("hello-world", tag="latest")
hello_world.stage(
"python",
"3.11-slim"
).entrypoint([
"echo",
"Hello world!"
])
```
the call to `entrypoint()` translates directly to:
```
ENTRYPOINT ["echo", "Hello world!"]
```
just like you would write in a Dockerfile.
Finally, we need to write our dcrx image to an actual Dockerfile! Let's chain a final call to `to_file()` passing `Dockerfile` as the sole argument.
```python
from dcrx import Image
hello_world = Image("hello-world", tag="latest")
hello_world.stage(
"python",
"3.11-slim"
).entrypoint([
"echo",
"Hello world!"
]).to_file("Dockerfile")
```
Now run the script:
```bash
python hello_world.py
```
You'll immediately see our `Dockerfile` is generated in-directory. Opening it up, we see:
```docker
FROM python:3.11-slim
ENTRYPOINT ["echo", "Hello world!"]
```
Now build your image as you normally would:
```bash
docker build -t hello-world:latest .
```
and run it:
```bash
docker run hello-world:latest
```
which outputs:
```bash
Hello world!
```
to console. The image works exactly like we'd expect it to! Congrats on building your first dcrx image!
<br/>
# Parsing and Resolving Images
As of version `0.3.0`, dcrx now facilitates image loading and resolution allowing you to ingest, simplify, and search Dockerfiles.
Let's start by creating the following `Dockerfile` in an empty directory of your choice:
```docker
# Dockerfile
ARG PYTHON_VERSION
ARG PYTHON_FILE=test.py
FROM python:${PYTHON_VERSION}
RUN apt-get update -y && apt-get install -y python3-dev
RUN mkdir /src
COPY ${PYTHON_FILE} /src
EXPOSE 8000
CMD ["python", ${PYTHON_FILE}]
```
This image tags two arguments, one for the Python version (with no default), and one specifying a Python script to copy and run.
We want generate a series of images for Python versions 3.10, 3.11, and 3.12. To do so, let's create a Python script `generate_python_images.py`. As before, we'll start by importing the `Image` class:
```python
# generate_python_images.py
from dcrx import Image
```
The image class has several methods to load images from files:
- `from_file()` - Loads the specified Dockerfile into the current `Image` instance.
- `from_string()` - Parses a Dockerfile already read as existing string, list of strings, bytes, or list of bytes into the current `Image` instance.
- `generate_from_file()` - Loads the specified Dockerfile and generates a new `Image` file instance. This is a `classmethod` and does not require an existing `Image` instance.
- `generate_from_string()` - Parses a Dockerfile already read as existing string, list of strings, bytes, or list of bytes and generates a new `Image` file instance. This is a `classmethod` and does not require an existing `Image` instance.
When choosing between `generate` or `from` methods, consider whether you want to generate a <i>new</i> `Image` or simply want to load a Dockerfile into and existing `Image`. In this case, since we want to generate a series of new image files, we'll use the `generate_from_file` method. Add the following to you Python script:
```python
# generate_python_images.py
from dcrx import Image
image_versions = [
'3.10-slim',
'3.11-slim',
'3.12-slim'
]
for version in image_versions:
version_stub = version.replace('.', '')
version_tag = f'python-{version_stub}'
image = Image.generate_from_file(
'Dockerfile.python-template',
output_path=f'Dockerfile.{version_tag}'
)
image.name = 'python'
image.tag = version_tag
print(image.path)
```
Go ahead and run the script:
```bash
python generate_python_images.py
```
which should output:
```bash
Dockerfile.python-310-slim
Dockerfile.python-311-slim
Dockerfile.python-312-slim
```
Awesome! We're able to generate the three distinct image instances. Let's explore our images a bit more. Let's examine our generated images' `FROM` directes via the `layers()` method. Modify your script as below:
```python
# generate_python_images.py
from dcrx import Image
image_versions = [
'3.10-slim',
'3.11-slim',
'3.12-slim'
]
for version in image_versions:
version_stub = version.replace('.', '')
version_tag = f'python-{version_stub}'
image = Image.generate_from_file(
'Dockerfile.python-template',
output_path=f'Dockerfile.{version_tag}'
)
image.name = 'python'
image.tag = version_tag
print(image.path)
stage_layers = image.layers(layer_types='stage')
for stage in stage_layers:
print(stage.base, stage.tag, '\n')
```
run the script again, which should output:
```bash
Dockerfile.python-310-slim
python ${PYTHON_VERSION}
Dockerfile.python-311-slim
python ${PYTHON_VERSION}
Dockerfile.python-312-slim
python ${PYTHON_VERSION}
```
while our script ran successfully, the images aren't build ready, still containing the templated arguments. This is where the `resolve()` method comes in! The `resolve()` method flood-fills an Image based upon any defaults supplied to `ARG` or `ENV` directes (or an optional dictionary specifying `ARG`/`ENV` names or keys and value defaults).
Let's modify our script once again as below:
```python
# generate_python_images.py
from dcrx import Image
image_versions = [
'3.10-slim',
'3.11-slim',
'3.12-slim'
]
for version in image_versions:
version_stub = version.replace('.', '')
version_tag = f'python-{version_stub}'
image = Image.generate_from_file(
'Dockerfile.python-template',
output_path=f'Dockerfile.{version_tag}'
)
image.name = 'python'
image.tag = version_tag
# Resolve our Image here:
image = image.resolve(
defaults={
# Note that since PYTHON_VERSION doesn't have
# a default, we should use the "defaults" optionsl
# arg to provide one from our array of versions.
'PYTHON_VERSION': version
}
)
stage_layers = image.layers(layer_types='stage')
for stage in stage_layers:
print(stage.base, stage.tag, '\n')
```
Run the script again, which should output:
```
python 3.10-slim
python 3.11-slim
python 3.12-slim
```
Let's modify the script once more, adding a call to `to_file()` to output our images to file:
```python
# generate_python_images.py
from dcrx import Image
image_versions = [
'3.10-slim',
'3.11-slim',
'3.12-slim'
]
for version in image_versions:
version_stub = version.replace('.', '')
version_tag = f'python-{version_stub}'
image = Image.generate_from_file(
'Dockerfile.python-template',
output_path=f'Dockerfile.{version_tag}'
)
image.name = 'python'
image.tag = version_tag
# Resolve our Image here:
image = image.resolve(
defaults={
'PYTHON_VERSION': version
}
)
image.to_file()
```
and run the script again:
```bash
python generate_python_images.py
```
Note that the script now generates three distinct Dockerfiles - `Dockerfile.python-310-slim`, `Dockerfile.python-311-slim`, and `Dockerfile.python-312-slim`. Let's examine, `Dockerfile.python-312-slim`:
```docker
ARG PYTHON_VERSION="3.12-slim"
ARG PYTHON_FILE="test.py"
FROM python:3.12-slim
RUN apt-get update -y && apt-get install -y python3-dev
RUN mkdir /src
COPY ./test.py /src
EXPOSE 8000
CMD ["python", "test.py"]
```
Not just `PYTHON_VERSION`, but any directive referencing `PYTHON_FILE` has been fully resolved to its default. While we want to resolve the `PYTHON_VERSION`, we may still want to specify `PYTHON_FILE` at build time. Let's modify the script once more, using the `skip` optional arg to ensure the `PYTHON_FILE` arg is not resolved:
```python
# generate_python_images.py
from dcrx import Image
image_versions = [
'3.10-slim',
'3.11-slim',
'3.12-slim'
]
for version in image_versions:
version_stub = version.replace('.', '')
version_tag = f'python-{version_stub}'
image = Image.generate_from_file(
'Dockerfile.python-template',
output_path=f'Dockerfile.{version_tag}'
)
image.name = 'python'
image.tag = version_tag
# Resolve our Image here:
image = image.resolve(
defaults={
'PYTHON_VERSION': version
},
skip=['PYTHON_FILE']
)
image.to_file()
```
and then run the script one final time:
```bash
python generate_python_image.py
```
Examining `Dockerfile.python-312-slim` once more:
```docker
ARG PYTHON_VERSION="3.12-slim"
ARG PYTHON_FILE="test.py"
FROM python:3.12-slim
RUN apt-get update -y && apt-get install -y python3-dev
RUN mkdir /src
COPY ./${PYTHON_FILE} /src
EXPOSE 8000
CMD ["python", "${PYTHON_FILE}"]
```
Perfect! We've now generated the Dockerfiles required!
Raw data
{
"_id": null,
"home_page": "https://github.com/scorbettUM/dcrx",
"name": "dcrx",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "",
"keywords": "pypi,cicd,python,setup,docker,infra,devops",
"author": "Sean Corbett",
"author_email": "sean.corbett@umontana.edu",
"download_url": "https://files.pythonhosted.org/packages/b9/11/9fe1aa80ab4223efdd905f7c4240502d414af8f9d7aa455c178c6f00b20c/dcrx-0.3.4.tar.gz",
"platform": null,
"description": "# dcrx\n[![PyPI version](https://img.shields.io/pypi/v/dcrx?color=gre)](https://pypi.org/project/dcrx/)\n[![License](https://img.shields.io/github/license/scorbettUM/dcrx)](https://github.com/scorbettUM/dcrx/blob/main/LICENSE)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/scorbettUM/dcrx/blob/main/CODE_OF_CONDUCT.md)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dcrx)](https://pypi.org/project/dcrx/)\n\n\nDockerX (dcrx) is a library for creating Docker images via an SQL query-builder like API. It is designed to facilitate programmatic, typesafe, and in-memory image generation. dcrx is *not* a wrapper around the Docker CLI or API, nor is it an implementation of these things. Rather, it is designed a lightweight, single-dependency means of writing and creating images that can then be provided to the Docker CLI or SDK for consumption.\n\n\n# Setup and Install\n\ndcrx is available via PyPi as an installable package. We recommend using Python 3.10+ and a virtual environment. To install dcrx, run:\n\n```bash\npython -m venv ~/.dcrx && \\\nsource ~/.dcrx/bin/activate && \\\npip install dcrx\n```\n\n\n# Getting Started\n\ndcrx uses a combination of method chaining common to SQL query builder libraries with Pydantic type validation to help you build images with fewer mistakes. As an example, let's create a basic Docker image that echoes \"Hello world!\" to output upon running the Docker image.\n\nFirst let's create an empty Python file:\n\n```\ntouch hello_world.py\n```\n\nOpen the file and import `Image` from `dcrx`:\n\n```python\nfrom dcrx import Image\n```\n\nThe Image class is the primary and only interface for generating and working with Docker images in dcrx. Let's go ahead and create an instance:\n\n```python\nfrom dcrx import Image\n\n\nhello_world = Image(\"hello-world\")\n```\n\nNote that we need to provide the name of the image to our class. We can also provide a tag via the `tag` keyword argument if needed (the default is `latest`):\n\n```python\nfrom dcrx import Image\n\nhello_world = Image(\"hello-world\", tag=\"latest\")\n```\n\nNext let's call the `stage()` method on our `hello_world` Image instance, passing both the base image name and image tag from which we want to create our image. We'll use `python` as our base image and `3.11-slim` as our tag:\n\n```python\nfrom dcrx import Image\n\nhello_world = Image(\"hello-world\", tag=\"latest\")\n\nhello_world.stage(\n \"python\",\n \"3.11-slim\"\n)\n```\n\nThis call translates directly to:\n\n```\nFROM python:3.11-slim\n```\n\nunderneath, just as if you were writing it in the image yourself! You can also use the optional `alias` arg to name the stage:\n\n```python\nfrom dcrx import Image\n\nhello_world = Image(\"hello-world\", tag=\"latest\")\n\nhello_world.stage(\n \"python\",\n \"3.11-slim\",\n alias=\"build\"\n)\n```\n\nwhich translates to:\n\n```\nFROM python:3.11-slim as build\n```\n\nThis is particularly useful for multi-stage builds.\n\nNext let's chain a call to the `entrypoint()` method, passing a list consisting of the CLI command (`echo` in this instance) and positional or keyword arguments/values we want to use:\n\n```python\nfrom dcrx import Image\n\nhello_world = Image(\"hello-world\", tag=\"latest\")\n\nhello_world.stage(\n \"python\",\n \"3.11-slim\"\n).entrypoint([\n \"echo\",\n \"Hello world!\"\n])\n```\n\nthe call to `entrypoint()` translates directly to:\n\n```\nENTRYPOINT [\"echo\", \"Hello world!\"]\n```\n\njust like you would write in a Dockerfile.\n\nFinally, we need to write our dcrx image to an actual Dockerfile! Let's chain a final call to `to_file()` passing `Dockerfile` as the sole argument.\n\n```python\nfrom dcrx import Image\n\nhello_world = Image(\"hello-world\", tag=\"latest\")\n\nhello_world.stage(\n \"python\",\n \"3.11-slim\"\n).entrypoint([\n \"echo\",\n \"Hello world!\"\n]).to_file(\"Dockerfile\")\n```\n\nNow run the script:\n\n```bash\npython hello_world.py\n```\n\nYou'll immediately see our `Dockerfile` is generated in-directory. Opening it up, we see:\n\n```docker\nFROM python:3.11-slim\n\nENTRYPOINT [\"echo\", \"Hello world!\"]\n```\n\nNow build your image as you normally would:\n\n```bash\ndocker build -t hello-world:latest .\n```\n\nand run it:\n\n```bash\ndocker run hello-world:latest\n```\n\nwhich outputs:\n\n```bash\nHello world!\n```\n\nto console. The image works exactly like we'd expect it to! Congrats on building your first dcrx image!\n\n<br/>\n\n# Parsing and Resolving Images\n\nAs of version `0.3.0`, dcrx now facilitates image loading and resolution allowing you to ingest, simplify, and search Dockerfiles.\n\nLet's start by creating the following `Dockerfile` in an empty directory of your choice:\n\n```docker\n# Dockerfile\nARG PYTHON_VERSION\nARG PYTHON_FILE=test.py\nFROM python:${PYTHON_VERSION}\n\nRUN apt-get update -y && apt-get install -y python3-dev\nRUN mkdir /src\n\nCOPY ${PYTHON_FILE} /src\n\nEXPOSE 8000\n\nCMD [\"python\", ${PYTHON_FILE}]\n```\n\nThis image tags two arguments, one for the Python version (with no default), and one specifying a Python script to copy and run.\n\nWe want generate a series of images for Python versions 3.10, 3.11, and 3.12. To do so, let's create a Python script `generate_python_images.py`. As before, we'll start by importing the `Image` class:\n\n```python\n# generate_python_images.py\nfrom dcrx import Image\n```\n\nThe image class has several methods to load images from files:\n\n- `from_file()` - Loads the specified Dockerfile into the current `Image` instance.\n\n- `from_string()` - Parses a Dockerfile already read as existing string, list of strings, bytes, or list of bytes into the current `Image` instance.\n\n- `generate_from_file()` - Loads the specified Dockerfile and generates a new `Image` file instance. This is a `classmethod` and does not require an existing `Image` instance.\n\n- `generate_from_string()` - Parses a Dockerfile already read as existing string, list of strings, bytes, or list of bytes and generates a new `Image` file instance. This is a `classmethod` and does not require an existing `Image` instance.\n\nWhen choosing between `generate` or `from` methods, consider whether you want to generate a <i>new</i> `Image` or simply want to load a Dockerfile into and existing `Image`. In this case, since we want to generate a series of new image files, we'll use the `generate_from_file` method. Add the following to you Python script:\n\n```python\n# generate_python_images.py\nfrom dcrx import Image\n\n\nimage_versions = [\n '3.10-slim',\n '3.11-slim',\n '3.12-slim'\n]\n\nfor version in image_versions:\n version_stub = version.replace('.', '')\n version_tag = f'python-{version_stub}'\n\n image = Image.generate_from_file(\n 'Dockerfile.python-template',\n output_path=f'Dockerfile.{version_tag}'\n )\n \n image.name = 'python'\n image.tag = version_tag\n\n print(image.path)\n```\n\nGo ahead and run the script:\n\n```bash\npython generate_python_images.py\n```\n\nwhich should output:\n\n```bash\nDockerfile.python-310-slim\nDockerfile.python-311-slim\nDockerfile.python-312-slim\n```\n\nAwesome! We're able to generate the three distinct image instances. Let's explore our images a bit more. Let's examine our generated images' `FROM` directes via the `layers()` method. Modify your script as below:\n\n```python\n# generate_python_images.py\nfrom dcrx import Image\n\n\nimage_versions = [\n '3.10-slim',\n '3.11-slim',\n '3.12-slim'\n]\n\nfor version in image_versions:\n version_stub = version.replace('.', '')\n version_tag = f'python-{version_stub}'\n\n image = Image.generate_from_file(\n 'Dockerfile.python-template',\n output_path=f'Dockerfile.{version_tag}'\n )\n \n image.name = 'python'\n image.tag = version_tag\n \n print(image.path)\n\n stage_layers = image.layers(layer_types='stage')\n for stage in stage_layers:\n print(stage.base, stage.tag, '\\n')\n```\n\nrun the script again, which should output:\n\n```bash\nDockerfile.python-310-slim\npython ${PYTHON_VERSION}\n\nDockerfile.python-311-slim\npython ${PYTHON_VERSION}\n\nDockerfile.python-312-slim\npython ${PYTHON_VERSION}\n```\n\nwhile our script ran successfully, the images aren't build ready, still containing the templated arguments. This is where the `resolve()` method comes in! The `resolve()` method flood-fills an Image based upon any defaults supplied to `ARG` or `ENV` directes (or an optional dictionary specifying `ARG`/`ENV` names or keys and value defaults).\n\nLet's modify our script once again as below:\n\n```python\n# generate_python_images.py\nfrom dcrx import Image\n\n\nimage_versions = [\n '3.10-slim',\n '3.11-slim',\n '3.12-slim'\n]\n\nfor version in image_versions:\n version_stub = version.replace('.', '')\n version_tag = f'python-{version_stub}'\n\n image = Image.generate_from_file(\n 'Dockerfile.python-template',\n output_path=f'Dockerfile.{version_tag}'\n )\n \n image.name = 'python'\n image.tag = version_tag\n \n # Resolve our Image here:\n image = image.resolve(\n defaults={\n # Note that since PYTHON_VERSION doesn't have\n # a default, we should use the \"defaults\" optionsl\n # arg to provide one from our array of versions.\n 'PYTHON_VERSION': version\n }\n )\n\n stage_layers = image.layers(layer_types='stage')\n for stage in stage_layers:\n print(stage.base, stage.tag, '\\n')\n```\n\nRun the script again, which should output:\n\n```\npython 3.10-slim\n\npython 3.11-slim\n\npython 3.12-slim\n```\n\nLet's modify the script once more, adding a call to `to_file()` to output our images to file: \n\n```python\n# generate_python_images.py\nfrom dcrx import Image\n\n\nimage_versions = [\n '3.10-slim',\n '3.11-slim',\n '3.12-slim'\n]\n\nfor version in image_versions:\n version_stub = version.replace('.', '')\n version_tag = f'python-{version_stub}'\n\n image = Image.generate_from_file(\n 'Dockerfile.python-template',\n output_path=f'Dockerfile.{version_tag}'\n )\n \n image.name = 'python'\n image.tag = version_tag\n \n # Resolve our Image here:\n image = image.resolve(\n defaults={\n 'PYTHON_VERSION': version\n }\n )\n\n image.to_file()\n```\n\nand run the script again:\n\n```bash\npython generate_python_images.py\n```\n\nNote that the script now generates three distinct Dockerfiles - `Dockerfile.python-310-slim`, `Dockerfile.python-311-slim`, and `Dockerfile.python-312-slim`. Let's examine, `Dockerfile.python-312-slim`:\n\n```docker\nARG PYTHON_VERSION=\"3.12-slim\"\n\nARG PYTHON_FILE=\"test.py\"\n\nFROM python:3.12-slim\n\nRUN apt-get update -y && apt-get install -y python3-dev\n\nRUN mkdir /src\n\nCOPY ./test.py /src\n\nEXPOSE 8000\n\nCMD [\"python\", \"test.py\"]\n```\n\nNot just `PYTHON_VERSION`, but any directive referencing `PYTHON_FILE` has been fully resolved to its default. While we want to resolve the `PYTHON_VERSION`, we may still want to specify `PYTHON_FILE` at build time. Let's modify the script once more, using the `skip` optional arg to ensure the `PYTHON_FILE` arg is not resolved:\n\n```python\n# generate_python_images.py\nfrom dcrx import Image\n\n\nimage_versions = [\n '3.10-slim',\n '3.11-slim',\n '3.12-slim'\n]\n\nfor version in image_versions:\n version_stub = version.replace('.', '')\n version_tag = f'python-{version_stub}'\n\n image = Image.generate_from_file(\n 'Dockerfile.python-template',\n output_path=f'Dockerfile.{version_tag}'\n )\n \n image.name = 'python'\n image.tag = version_tag\n \n # Resolve our Image here:\n image = image.resolve(\n defaults={\n 'PYTHON_VERSION': version\n },\n skip=['PYTHON_FILE']\n )\n\n image.to_file()\n```\n\nand then run the script one final time:\n\n```bash\npython generate_python_image.py\n```\n\nExamining `Dockerfile.python-312-slim` once more:\n\n```docker\nARG PYTHON_VERSION=\"3.12-slim\"\n\nARG PYTHON_FILE=\"test.py\"\n\nFROM python:3.12-slim\n\nRUN apt-get update -y && apt-get install -y python3-dev\n\nRUN mkdir /src\n\nCOPY ./${PYTHON_FILE} /src\n\nEXPOSE 8000\n\nCMD [\"python\", \"${PYTHON_FILE}\"]\n```\n\nPerfect! We've now generated the Dockerfiles required!\n",
"bugtrack_url": null,
"license": "",
"summary": "A library for typesafe, programmatic generation of Docker images via SQL-builder like API.",
"version": "0.3.4",
"project_urls": {
"Homepage": "https://github.com/scorbettUM/dcrx"
},
"split_keywords": [
"pypi",
"cicd",
"python",
"setup",
"docker",
"infra",
"devops"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "679db773b43083839fc1320a4716e136c03d998c0bedd5356c356239e4803c06",
"md5": "c43b95eaa7300ab676ed60f6dae9a8e2",
"sha256": "f772af82df7a0ee9daab87d06208e03bc905ddcbbeebf298a47070123a719f1c"
},
"downloads": -1,
"filename": "dcrx-0.3.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c43b95eaa7300ab676ed60f6dae9a8e2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 31445,
"upload_time": "2024-01-18T21:34:26",
"upload_time_iso_8601": "2024-01-18T21:34:26.190575Z",
"url": "https://files.pythonhosted.org/packages/67/9d/b773b43083839fc1320a4716e136c03d998c0bedd5356c356239e4803c06/dcrx-0.3.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b9119fe1aa80ab4223efdd905f7c4240502d414af8f9d7aa455c178c6f00b20c",
"md5": "a8136b516e031e5598f2b5dc2dc9ce6c",
"sha256": "1ac80d198bbf8af49582563fc4600f1ba17b07b9556bfaa1ad4f97f17f5ddfa0"
},
"downloads": -1,
"filename": "dcrx-0.3.4.tar.gz",
"has_sig": false,
"md5_digest": "a8136b516e031e5598f2b5dc2dc9ce6c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 23368,
"upload_time": "2024-01-18T21:34:27",
"upload_time_iso_8601": "2024-01-18T21:34:27.860803Z",
"url": "https://files.pythonhosted.org/packages/b9/11/9fe1aa80ab4223efdd905f7c4240502d414af8f9d7aa455c178c6f00b20c/dcrx-0.3.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-18 21:34:27",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "scorbettUM",
"github_project": "dcrx",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pydantic",
"specs": []
}
],
"lcname": "dcrx"
}