<!--- Top of README Badges (automated) --->
[](https://pypi.org/project/wipac-file-catalog/) [](https://github.com/WIPACrepo/file_catalog/) [](https://github.com/WIPACrepo/file_catalog/blob/master/LICENSE) [](https://github.com/WIPACrepo/file_catalog/) [](https://github.com/WIPACrepo/file_catalog/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aopen) [](https://github.com/WIPACrepo/file_catalog/pulls?q=is%3Apr+sort%3Aupdated-desc+is%3Aopen)
<!--- End of README Badges (automated) --->
# file_catalog
Store file metadata information in a file catalog
## Prerequisites
To get the prerequisites necessary for the file catalog:
pip install -r requirements.txt
## Running the server
To start an instance of the server running:
python -m file_catalog
## Configuration
All configuration is done using environment variables.
To get the list of possible configuration parameters and their defaults, run
python -m file_catalog --show-config-spec
## Interface
The primary interface is an HTTP server. TLS and other security
hardening mechanisms are handled by a reverse proxy server as
for normal web applications.
## Browser
Requests to the main url `/` are browsable like a standard website.
They will use javascript to activate the REST API as necessary.
## REST API
Requests with urls of the form `/api/RESOURCE` can access the
REST API. Responses are in [HAL](http://stateless.co/hal_specification.html)
JSON format.
### File-Entry Fields
#### File-Metadata Schema:
* _See [types.py](https://github.com/WIPACrepo/file_catalog/blob/master/file_catalog/schema/types.py)_
#### Mandatory Fields:
* `uuid` (provided by File Catalog)
* `logical_name`
* `locations` (with at least one non-empty URL)
* `file_size`
* `checksum.sha512`
### Route: `/api/files`
Resource representing the collection of all files in the catalog.
#### Method: `GET`
Obtain list of files
##### REST-Query Parameters
* [`limit`](#limit)
* [`start`](#start)
* [`logical_name`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*
* [`directory`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*
* [`filename`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*
* [`logical-name-regex`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*
* [`run_number`](#shortcut-parameter-run_number) *(shortcut parameter)*
* [`dataset`](#shortcut-parameter-dataset) *(shortcut parameter)*
* [`event_id`](#shortcut-parameter-event_id) *(shortcut parameter)*
* [`processing_level`](#shortcut-parameter-processing_level) *(shortcut parameter)*
* [`season`](#shortcut-parameter-season) *(shortcut parameter)*
* [`query`](#query)
* [`keys`](#keys)
* [`all-keys`](#shortcut-parameter-all-keys) *(shortcut parameter)*
* [`max_time_ms`](#max_time_ms)
##### HTTP Response Status Codes
* `200`: Response contains collection of file resources
* `400`: Bad request (query parameters invalid)
* `429`: Too many requests (if server is being hammered)
* `500`: Unspecified server error
* `503`: Service unavailable (maintenance, etc.)
#### Method: `POST`
Create a new file or add a replica
*If a file exists and the checksum is the same, a replica is added. If the checksum is different a conflict error is returned.*
##### REST-Body
* *See [File-Entry Fields](#File-Entry-Fields)*
##### HTTP Response Status Codes
* `200`: Replica has been added. Response contains link to file resource
* `201`: Response contains link to newly created file resource
* `400`: Bad request (metadata failed validation)
* `409`: Conflict (if the file-version already exists); includes link to existing file
* `429`: Too many requests (if server is being hammered)
* `500`: Unspecified server error
* `503`: Service unavailable (maintenance, etc.)
#### Method: `DELETE`
*Not supported*
#### Method: `PUT`
*Not supported*
#### Method: `PATCH`
*Not supported*
### Route: `/api/files/{uuid}`
Resource representing the metadata for a file in the file catalog.
#### Method: `GET`
Obtain file metadata information
##### REST-Query Parameters
* *None*
##### HTTP Response Status Codes
* `200`: Response contains metadata of file resource
* `404`: Not Found (file resource does not exist)
* `429`: Too many requests (if server is being hammered)
* `500`: Unspecified server error
* `503`: Service unavailable (maintenance, etc.)
#### Method: `POST`
*Not supported*
#### Method: `DELETE`
Delete the metadata for the file
##### REST-Query Parameters
* *None*
##### HTTP Response Status Codes
* `204`: No Content (file resource is successfully deleted)
* `404`: Not Found (file resource does not exist)
* `429`: Too many requests (if server is being hammered)
* `500`: Unspecified server error
* `503`: Service unavailable (maintenance, etc.)
#### Method: `PUT `
Fully update/replace file metadata information
##### REST-Body
* *See [File-Entry Fields](#File-Entry-Fields)*
##### HTTP Response Status Codes
* `200`: Response indicates metadata of file resource has been updated/replaced
* `404`: Not Found (file resource does not exist) + link to “files” resource for POST
* `409`: Conflict (if updating an outdated resource - use ETAG hash to compare)
* `429`: Too many requests (if server is being hammered)
* `500`: Unspecified server error
* `503`: Service unavailable (maintenance, etc.)
#### Method: `PATCH`
Partially update/replace file metadata information
*The JSON provided as body to PATCH need not contain all the keys, only the need to be updated. If a key is provided with a value null, then that key can be removed from the metadata.*
##### REST-Body
* *See [File-Entry Fields](#File-Entry-Fields)*
##### HTTP Response Status Codes
* `200`: Response indicates metadata of file resource has been updated/replaced
* `404`: Not Found (file resource does not exist) + link to “files” resource for POST
* `409`: Conflict (if updating an outdated resource - use ETAG hash to compare)
* `429`: Too many requests (if server is being hammered)
* `500`: Unspecified server error
* `503`: Service unavailable (maintenance, etc.)
### More About REST-Query Parameters
##### `limit`
- *positive integer;* number of results to provide *(default: 10000)*
- **NOTE:** The server *may* honor the `limit` parameter. In cases where the server does not honor the `limit` parameter, it should do so by providing fewer resources (`limit` should be considered the client’s upper limit for the number of resources in the response).
##### `start`
- *non-negative integer;* result at which to start at *(default: 0)*
- **NOTE:** the server *should* honor the `start` parameter
- **TIP:** increment `start` by `limit` to paginate through many results
##### `query`
- *MongoDB query;* use to specify file-entry fields/ranges; forwarded to MongoDB daemon
##### `keys`
- *a `|`-delimited string-list of keys;* defines what fields to include in result(s)
- ex: `"foo|bar|baz"`
- different routes/methods define differing defaults
- **NOTE:** there is no performance hit for including more fields
- *see [`all-keys`](#shortcut-parameter-all-keys)*
##### `max_time_ms`
- *non-negative integer OR `None`;* timeout to kill long queries in MILLISECONDS
- overrides the default timeout of 600000 ms (10 minutes)
- `None` indicates no timeout (this can hang the server -- you have been warned)
##### Shortcut Parameters: `logical-name-regex`, `logical_name`, `directory`, `filename`
*In decreasing order of precedence...*
- `logical-name-regex`
- query by regex pattern (at your own risk... performance-wise)
- equivalent to: `query: {"logical_name": {"$regex": p}}`
- `logical_name`
- equivalent to: `query["logical_name"]`
- `directory`
- query by absolute directory filepath
- equivalent to: `query: {"logical_name": {"$regex": "^/your/path/.*"}}`
- **NOTE:** a trailing-`/` will be inserted if you don't provide one
- **TIP:** use in conjunction with `filename` (ie: `/root/dirs/.../filename`)
- `filename`
- query by filename (no parent-directory path needed)
- equivalent to: `query: {"logical_name": {"$regex": ".*/your-file$"}}`
- **NOTE:** a leading-`/` will be inserted if you don't provide one
- **TIP:** use in conjunction with `directory` (ie: `/root/dirs/.../filename`)
##### Shortcut Parameter: `run_number`
- equivalent to: `query["run.run_number"]`
##### Shortcut Parameter: `dataset`
- equivalent to: `query["iceprod.dataset"]`
##### Shortcut Parameter: `event_id`
- equivalent to: `query: {"run.first_event":{"$lte": e}, "run.last_event":{"$gte": e}}`
##### Shortcut Parameter: `processing_level`
- equivalent to: `query["processing_level"]`
##### Shortcut Parameter: `season`
- equivalent to: `query["offline_processing_metadata.season"]`
##### Shortcut Parameter: `all-keys`
- *boolean (`True`/`"True"`/`"true"`/`1`);* include *all fields* in result(s)
- **NOTE:** there is no performance hit for including more fields
- **TIP:** this is preferred over querying `/api/files`, grabbing the uuid, then querying `/api/files/{uuid}`
## Development
### Establishing a development environment
Follow these steps to get a development environment for the File Catalog:
cd ~/projects
git clone git@github.com:WIPACrepo/file_catalog.git
cd file_catalog
./setupenv.sh
### MongoDB Instance for Testing
This command will spin up a disposable MongoDB instance using Docker:
docker run \
--detach \
--name test-mongo \
--network=host \
--rm \
circleci/mongo:latest-ram
### Building a Docker container
The following commands will create a Docker container for the file-catalog:
docker build -t file-catalog:{version} -f Dockerfile .
docker image tag file-catalog:{version} file-catalog:latest
Where {version} is found in file_catalog/__init__py; e.g.:
__version__ = '1.2.0' # For {version} use: 1.2.0
### Pushing Docker containers to local registry in Kubernetes
Here are some commands to get the Docker container pushed to our Docker
register in our Kubernetes cluster:
kubectl -n kube-system port-forward $(kubectl get pods --namespace kube-system -l "app=docker-registry,release=docker-registry" -o jsonpath="{.items[0].metadata.name}") 5000:5000 &
docker tag file-catalog:{version} localhost:5000/file-catalog:{version}
docker push localhost:5000/file-catalog:{version}
Raw data
{
"_id": null,
"home_page": "https://github.com/WIPACrepo/file_catalog",
"name": "wipac-file-catalog",
"maintainer": "",
"docs_url": null,
"requires_python": "<3.12,>=3.8",
"maintainer_email": "",
"keywords": "metadata,data,warehouse,archive,L2,PFDST,PFFilt,PFRaw,i3,simulation,iceprod,WIPAC,IceCube",
"author": "WIPAC Developers",
"author_email": "developers@icecube.wisc.edu",
"download_url": "https://files.pythonhosted.org/packages/64/cb/266e5aad30ce6e64c9a36588d64a5c22e1e5d452803b4a89b11b5862cbc3/wipac-file-catalog-1.9.8.tar.gz",
"platform": null,
"description": "<!--- Top of README Badges (automated) --->\n[](https://pypi.org/project/wipac-file-catalog/) [](https://github.com/WIPACrepo/file_catalog/) [](https://github.com/WIPACrepo/file_catalog/blob/master/LICENSE) [](https://github.com/WIPACrepo/file_catalog/) [](https://github.com/WIPACrepo/file_catalog/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aopen) [](https://github.com/WIPACrepo/file_catalog/pulls?q=is%3Apr+sort%3Aupdated-desc+is%3Aopen) \n<!--- End of README Badges (automated) --->\n# file_catalog\nStore file metadata information in a file catalog\n\n\n\n## Prerequisites\nTo get the prerequisites necessary for the file catalog:\n\n pip install -r requirements.txt\n\n\n\n## Running the server\nTo start an instance of the server running:\n\n python -m file_catalog\n\n\n\n## Configuration\nAll configuration is done using environment variables.\nTo get the list of possible configuration parameters and their defaults, run\n\n python -m file_catalog --show-config-spec\n\n\n\n## Interface\nThe primary interface is an HTTP server. TLS and other security\nhardening mechanisms are handled by a reverse proxy server as\nfor normal web applications.\n\n\n\n## Browser\nRequests to the main url `/` are browsable like a standard website.\nThey will use javascript to activate the REST API as necessary.\n\n\n\n## REST API\nRequests with urls of the form `/api/RESOURCE` can access the\nREST API. Responses are in [HAL](http://stateless.co/hal_specification.html)\nJSON format.\n\n\n### File-Entry Fields\n\n#### File-Metadata Schema:\n* _See [types.py](https://github.com/WIPACrepo/file_catalog/blob/master/file_catalog/schema/types.py)_\n\n#### Mandatory Fields:\n* `uuid` (provided by File Catalog)\n* `logical_name`\n* `locations` (with at least one non-empty URL)\n* `file_size`\n* `checksum.sha512`\n\n\n### Route: `/api/files`\nResource representing the collection of all files in the catalog.\n\n\n#### Method: `GET`\nObtain list of files\n\n##### REST-Query Parameters\n * [`limit`](#limit)\n * [`start`](#start)\n * [`logical_name`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*\n * [`directory`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*\n * [`filename`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*\n * [`logical-name-regex`](#shortcut-parameters-logical-name-regex-logical_name-directory-filename) *(shortcut parameter)*\n * [`run_number`](#shortcut-parameter-run_number) *(shortcut parameter)*\n * [`dataset`](#shortcut-parameter-dataset) *(shortcut parameter)*\n * [`event_id`](#shortcut-parameter-event_id) *(shortcut parameter)*\n * [`processing_level`](#shortcut-parameter-processing_level) *(shortcut parameter)*\n * [`season`](#shortcut-parameter-season) *(shortcut parameter)*\n * [`query`](#query)\n * [`keys`](#keys)\n * [`all-keys`](#shortcut-parameter-all-keys) *(shortcut parameter)*\n * [`max_time_ms`](#max_time_ms)\n\n##### HTTP Response Status Codes\n * `200`: Response contains collection of file resources\n * `400`: Bad request (query parameters invalid)\n * `429`: Too many requests (if server is being hammered)\n * `500`: Unspecified server error\n * `503`: Service unavailable (maintenance, etc.)\n\n#### Method: `POST`\nCreate a new file or add a replica\n\n*If a file exists and the checksum is the same, a replica is added. If the checksum is different a conflict error is returned.*\n\n##### REST-Body\n * *See [File-Entry Fields](#File-Entry-Fields)*\n\n##### HTTP Response Status Codes\n * `200`: Replica has been added. Response contains link to file resource\n * `201`: Response contains link to newly created file resource\n * `400`: Bad request (metadata failed validation)\n * `409`: Conflict (if the file-version already exists); includes link to existing file\n * `429`: Too many requests (if server is being hammered)\n * `500`: Unspecified server error\n * `503`: Service unavailable (maintenance, etc.)\n\n#### Method: `DELETE`\n*Not supported*\n\n#### Method: `PUT`\n*Not supported*\n\n#### Method: `PATCH`\n*Not supported*\n\n\n### Route: `/api/files/{uuid}`\nResource representing the metadata for a file in the file catalog.\n\n#### Method: `GET`\nObtain file metadata information\n\n##### REST-Query Parameters\n * *None*\n\n##### HTTP Response Status Codes\n * `200`: Response contains metadata of file resource\n * `404`: Not Found (file resource does not exist)\n * `429`: Too many requests (if server is being hammered)\n * `500`: Unspecified server error\n * `503`: Service unavailable (maintenance, etc.)\n\n#### Method: `POST`\n*Not supported*\n\n#### Method: `DELETE`\nDelete the metadata for the file\n\n##### REST-Query Parameters\n * *None*\n\n##### HTTP Response Status Codes\n * `204`: No Content (file resource is successfully deleted)\n * `404`: Not Found (file resource does not exist)\n * `429`: Too many requests (if server is being hammered)\n * `500`: Unspecified server error\n * `503`: Service unavailable (maintenance, etc.)\n\n#### Method: `PUT `\nFully update/replace file metadata information\n\n##### REST-Body\n * *See [File-Entry Fields](#File-Entry-Fields)*\n\n##### HTTP Response Status Codes\n * `200`: Response indicates metadata of file resource has been updated/replaced\n * `404`: Not Found (file resource does not exist) + link to \u201cfiles\u201d resource for POST\n * `409`: Conflict (if updating an outdated resource - use ETAG hash to compare)\n * `429`: Too many requests (if server is being hammered)\n * `500`: Unspecified server error\n * `503`: Service unavailable (maintenance, etc.)\n\n#### Method: `PATCH`\nPartially update/replace file metadata information\n\n*The JSON provided as body to PATCH need not contain all the keys, only the need to be updated. If a key is provided with a value null, then that key can be removed from the metadata.*\n\n##### REST-Body\n * *See [File-Entry Fields](#File-Entry-Fields)*\n\n##### HTTP Response Status Codes\n * `200`: Response indicates metadata of file resource has been updated/replaced\n * `404`: Not Found (file resource does not exist) + link to \u201cfiles\u201d resource for POST\n * `409`: Conflict (if updating an outdated resource - use ETAG hash to compare)\n * `429`: Too many requests (if server is being hammered)\n * `500`: Unspecified server error\n * `503`: Service unavailable (maintenance, etc.)\n\n\n### More About REST-Query Parameters\n\n##### `limit`\n- *positive integer;* number of results to provide *(default: 10000)*\n- **NOTE:** The server *may* honor the `limit` parameter. In cases where the server does not honor the `limit` parameter, it should do so by providing fewer resources (`limit` should be considered the client\u2019s upper limit for the number of resources in the response).\n\n##### `start`\n- *non-negative integer;* result at which to start at *(default: 0)*\n- **NOTE:** the server *should* honor the `start` parameter\n- **TIP:** increment `start` by `limit` to paginate through many results\n\n##### `query`\n- *MongoDB query;* use to specify file-entry fields/ranges; forwarded to MongoDB daemon\n\n##### `keys`\n- *a `|`-delimited string-list of keys;* defines what fields to include in result(s)\n- ex: `\"foo|bar|baz\"`\n- different routes/methods define differing defaults\n- **NOTE:** there is no performance hit for including more fields\n- *see [`all-keys`](#shortcut-parameter-all-keys)*\n\n##### `max_time_ms`\n- *non-negative integer OR `None`;* timeout to kill long queries in MILLISECONDS\n- overrides the default timeout of 600000 ms (10 minutes)\n- `None` indicates no timeout (this can hang the server -- you have been warned)\n\n##### Shortcut Parameters: `logical-name-regex`, `logical_name`, `directory`, `filename`\n*In decreasing order of precedence...*\n- `logical-name-regex`\n - query by regex pattern (at your own risk... performance-wise)\n - equivalent to: `query: {\"logical_name\": {\"$regex\": p}}`\n\n- `logical_name`\n - equivalent to: `query[\"logical_name\"]`\n\n- `directory`\n - query by absolute directory filepath\n - equivalent to: `query: {\"logical_name\": {\"$regex\": \"^/your/path/.*\"}}`\n - **NOTE:** a trailing-`/` will be inserted if you don't provide one\n - **TIP:** use in conjunction with `filename` (ie: `/root/dirs/.../filename`)\n\n- `filename`\n - query by filename (no parent-directory path needed)\n - equivalent to: `query: {\"logical_name\": {\"$regex\": \".*/your-file$\"}}`\n - **NOTE:** a leading-`/` will be inserted if you don't provide one\n - **TIP:** use in conjunction with `directory` (ie: `/root/dirs/.../filename`)\n\n##### Shortcut Parameter: `run_number`\n- equivalent to: `query[\"run.run_number\"]`\n\n\n##### Shortcut Parameter: `dataset`\n- equivalent to: `query[\"iceprod.dataset\"]`\n\n\n##### Shortcut Parameter: `event_id`\n- equivalent to: `query: {\"run.first_event\":{\"$lte\": e}, \"run.last_event\":{\"$gte\": e}}`\n\n\n##### Shortcut Parameter: `processing_level`\n- equivalent to: `query[\"processing_level\"]`\n\n\n##### Shortcut Parameter: `season`\n- equivalent to: `query[\"offline_processing_metadata.season\"]`\n\n##### Shortcut Parameter: `all-keys`\n- *boolean (`True`/`\"True\"`/`\"true\"`/`1`);* include *all fields* in result(s)\n- **NOTE:** there is no performance hit for including more fields\n- **TIP:** this is preferred over querying `/api/files`, grabbing the uuid, then querying `/api/files/{uuid}`\n\n\n\n## Development\n\n### Establishing a development environment\nFollow these steps to get a development environment for the File Catalog:\n\n cd ~/projects\n git clone git@github.com:WIPACrepo/file_catalog.git\n cd file_catalog\n ./setupenv.sh\n\n### MongoDB Instance for Testing\nThis command will spin up a disposable MongoDB instance using Docker:\n\n docker run \\\n --detach \\\n --name test-mongo \\\n --network=host \\\n --rm \\\n circleci/mongo:latest-ram\n\n### Building a Docker container\nThe following commands will create a Docker container for the file-catalog:\n\n docker build -t file-catalog:{version} -f Dockerfile .\n docker image tag file-catalog:{version} file-catalog:latest\n\nWhere {version} is found in file_catalog/__init__py; e.g.:\n\n __version__ = '1.2.0' # For {version} use: 1.2.0\n\n### Pushing Docker containers to local registry in Kubernetes\nHere are some commands to get the Docker container pushed to our Docker\nregister in our Kubernetes cluster:\n\n kubectl -n kube-system port-forward $(kubectl get pods --namespace kube-system -l \"app=docker-registry,release=docker-registry\" -o jsonpath=\"{.items[0].metadata.name}\") 5000:5000 &\n docker tag file-catalog:{version} localhost:5000/file-catalog:{version}\n docker push localhost:5000/file-catalog:{version}\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Store file metadata information in a file catalog",
"version": "1.9.8",
"project_urls": {
"Download": "https://pypi.org/project/wipac-file-catalog/",
"Homepage": "https://github.com/WIPACrepo/file_catalog",
"Source": "https://github.com/WIPACrepo/file_catalog",
"Tracker": "https://github.com/WIPACrepo/file_catalog/issues"
},
"split_keywords": [
"metadata",
"data",
"warehouse",
"archive",
"l2",
"pfdst",
"pffilt",
"pfraw",
"i3",
"simulation",
"iceprod",
"wipac",
"icecube"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d8a4a239a88dd31cf88b36ee8bf46d1a3d8abb970d590976e630b1a84e2d02b5",
"md5": "411ab1308b8eb064f88b3201b41c786b",
"sha256": "6130c41e0c8fd914b2dc721d5c6ad00fe0a0c5db0f0a990fd51b6cdf64eeb87f"
},
"downloads": -1,
"filename": "wipac_file_catalog-1.9.8-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "411ab1308b8eb064f88b3201b41c786b",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": "<3.12,>=3.8",
"size": 30072,
"upload_time": "2023-05-30T14:15:47",
"upload_time_iso_8601": "2023-05-30T14:15:47.324928Z",
"url": "https://files.pythonhosted.org/packages/d8/a4/a239a88dd31cf88b36ee8bf46d1a3d8abb970d590976e630b1a84e2d02b5/wipac_file_catalog-1.9.8-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "64cb266e5aad30ce6e64c9a36588d64a5c22e1e5d452803b4a89b11b5862cbc3",
"md5": "fcc78153705d304bc7918cf4b413c8f1",
"sha256": "a2bc9f74d97f5b4a56980ef3ba872ffb49a0637952956b1d2f67587ae011a700"
},
"downloads": -1,
"filename": "wipac-file-catalog-1.9.8.tar.gz",
"has_sig": false,
"md5_digest": "fcc78153705d304bc7918cf4b413c8f1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.12,>=3.8",
"size": 29494,
"upload_time": "2023-05-30T14:15:49",
"upload_time_iso_8601": "2023-05-30T14:15:49.140139Z",
"url": "https://files.pythonhosted.org/packages/64/cb/266e5aad30ce6e64c9a36588d64a5c22e1e5d452803b4a89b11b5862cbc3/wipac-file-catalog-1.9.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-30 14:15:49",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "WIPACrepo",
"github_project": "file_catalog",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "wipac-file-catalog"
}