# joppy
Python interface for the [Joplin data API](https://joplinapp.org/api/references/rest_api/) (client) and the Joplin server API.
[](https://github.com/marph91/joppy/actions/workflows/build.yml)
[](https://github.com/marph91/joppy/actions/workflows/lint.yml)
[](https://github.com/marph91/joppy/actions/workflows/tests.yml)
[](https://codecov.io/gh/marph91/joppy)
[](https://github.com/laurent22/joplin)
[](https://pypi.python.org/pypi/joppy/)
## Features
| | Client API Wrapper | Server API Wrapper |
| --- | --- | --- |
| **Supported** | All functions from the [data API](https://joplinapp.org/help/api/references/rest_api/) | Some reverse engineered functions with a similar interface like the client API wrapper. See the example below and the source code for details. |
| **Not Supported** | - | - Encryption <br>- Some functions that were either to complex or I didn't see a use for automation. |
## :computer: Installation
From pypi:
```bash
pip install joppy
```
From source:
```bash
git clone https://github.com/marph91/joppy.git
cd joppy
pip install .
```
## :wrench: Usage
Please backup your data before use!
### General function description
- `add_<type>()`: Create a new element.
- `delete_<type>()`: Delete an element by ID.
- `get_<type>()`: Get an element by ID.
- `get_all_<type>()`: Get all elements of a kind.
- `modify_<type>()`: Modify an elements property by ID.
- `search_all()`: Search elements using [joplins search engine](https://joplinapp.org/api/references/rest_api/#searching).
For details, consult the [implementation](joppy/api.py), [joplin documentation](https://joplinapp.org/api/references/rest_api/) or [create an issue](https://github.com/marph91/joppy/issues).
## :bulb: Example snippets
### Client API
Start joplin and [get your API token](https://joplinapp.org/api/references/rest_api/#authorisation). Click to expand the examples.
<details>
<summary>Get all notes</summary>
```python name=get_all_notes
from joppy.client_api import ClientApi
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
# Get all notes. Note that this method calls get_notes() multiple times to assemble the unpaginated result.
notes = api.get_all_notes()
```
</details>
<details>
<summary>Add a tag to a note</summary>
```python name=add_tag_to_note
from joppy.client_api import ClientApi
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
# Add a notebook.
notebook_id = api.add_notebook(title="My first notebook")
# Add a note in the previously created notebook.
note_id = api.add_note(title="My first note", body="With some content", parent_id=notebook_id)
# Add a tag, that is not yet attached to a note.
tag_id = api.add_tag(title="introduction")
# Link the tag to the note.
api.add_tag_to_note(tag_id=tag_id, note_id=note_id)
````
</details>
<details>
<summary>Add a resource to a note</summary>
```python name=add_resource_to_note
from joppy.client_api import ClientApi
from joppy import tools
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
# Add a notebook.
notebook_id = api.add_notebook(title="My first notebook")
# Option 1: Add a note with an image data URL. This works only for images.
image_data = tools.encode_base64("path/to/image.png")
api.add_note(
title="My first note",
image_data_url=f"data:image/png;base64,{image_data}",
)
# Option 2: Create note and resource separately. Link them later. This works for arbitrary attachments.
note_id = api.add_note(title="My second note")
resource_id = api.add_resource(filename="path/to/image.png", title="My first resource")
api.add_resource_to_note(resource_id=resource_id, note_id=note_id)
````
</details>
<details>
<summary>Bulk remove tags</summary>
Inspired by <https://discourse.joplinapp.org/t/bulk-tag-delete-python-script/5497/1>.
```python name=remove_tags
import re
from joppy.client_api import ClientApi
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
# Iterate through all tags.
for tag in api.get_all_tags():
# Delete all tags that match the regex. I. e. start with "!".
if re.search("^!", tag.title) is not None:
api.delete_tag(tag.id)
```
</details>
<details>
<summary>Remove unused tags</summary>
Reference: <https://discourse.joplinapp.org/t/prune-empty-tags-from-web-clipper/36194>
```python name=remove_unused_tags
from joppy.client_api import ClientApi
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
for tag in api.get_all_tags():
notes_for_tag = api.get_all_notes(tag_id=tag.id)
if len(notes_for_tag) == 0:
print("Deleting tag:", tag.title)
api.delete_tag(tag.id)
```
</details>
<details>
<summary>Remove spaces from tags</summary>
Reference: <https://www.reddit.com/r/joplinapp/comments/pozric/batch_remove_spaces_from_all_tags/>
```python name=remove_spaces_from_tags
import re
from joppy.client_api import ClientApi
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
# Define the conversion function.
def to_camel_case(name: str) -> str:
name = re.sub(r"(_|-)+", " ", name).title().replace(" ", "")
return "".join([name[0].lower(), name[1:]])
# Iterate through all tags and apply the conversion.
for tag in api.get_all_tags():
api.modify_tag(id_=tag.id, title=to_camel_case(tag.title))
```
</details>
<details>
<summary>Remove orphaned resources</summary>
Inspired by <https://discourse.joplinapp.org/t/joplin-vacuum-a-python-script-to-remove-orphaned-resources/19742>.
Note: The note history is not considered. See: <https://discourse.joplinapp.org/t/joplin-vacuum-a-python-script-to-remove-orphaned-resources/19742/13>.
```python name=remove_orphaned_resources
import re
from joppy.client_api import ClientApi
# Create a new Api instance.
api = ClientApi(token=YOUR_TOKEN)
# Getting the referenced resource directly doesn't work:
# https://github.com/laurent22/joplin/issues/4535
# So we have to find the referenced resources by regex.
# Iterate through all notes and find the referenced resources.
referenced_resources = set()
for note in api.get_all_notes(fields="id,body"):
matches = re.findall(r"\[.*\]\(:.*\/([A-Za-z0-9]{32})\)", note.body)
referenced_resources.update(matches)
assert len(referenced_resources) > 0, "sanity check"
for resource in api.get_all_resources():
if resource.id not in referenced_resources:
print("Deleting resource:", resource.title)
api.delete_resource(resource.id)
```
</details>
For more usage examples, check the example scripts or [tests](test/test_client_api.py).
### Server API
The server API should work similarly to the client API in most cases. **Be aware that the server API is experimental and may break at any time. I can't provide any help at sync issues or lost data. Make sure you have a backup and know how to restore it.**
```python
from joppy.server_api import ServerApi
# Create a new Api instance.
api = ServerApi(user="admin@localhost", password="admin", url="http://localhost:22300")
# Acquire a lock.
with api.sync_lock():
# Add a notebook.
notebook_id = api.add_notebook(title="My first notebook")
# Add a note in the previously created notebook.
note_id = api.add_note(title="My first note", body="With some content", parent_id=notebook_id)
```
## :newspaper: Examples
Before using joppy, you should check the [Joplin plugins](https://joplinapp.org/plugins/). They are probably more convenient. However, if you need a new feature or just want to code in python, you can use joppy.
### Apps
| App | Description |
| --- | --- |
| [jimmy](https://github.com/marph91/jimmy) | A tool to import your notes to Joplin |
| [joplin-sticky-notes](https://github.com/marph91/joplin-sticky-notes) | Stick your Joplin notes to the desktop |
| [joplin-vieweb](https://github.com/joplin-vieweb/django-joplin-vieweb) | A simple web viewer for Joplin |
### Scripts
| Script | Description |
| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [custom_export.py](examples/custom_export.py) | Export resources next to notes, instead of a separate folder. |
| [note_export.py](examples/note_export.py) | Export notes to any format supported by [pandoc](https://pandoc.org/). |
| [note_stats.py](examples/note_stats.py) | Get some simple statistics about your notes, based on [nltk](https://www.nltk.org/). |
| [note_tree_export.py](examples/note_tree_export.py) | Joplin only supports PDF export of a single note. This script allows to export one, multiple or all notebooks to PDF or TXT. |
| [visualize_note_locations.py](examples/visualize_note_locations.py) | Visualize the locations of your notes. |
| [joplin-ui-tests](https://github.com/marph91/joplin-ui-tests) | System tests for the joplin desktop app. Based on selenium. |
## :sunny: Tests
To run the tests, some additional system packages and python modules are needed. After installing them, just run:
```bash
python -m unittest
```
It's possible to configure the test run via some environment variables:
- `SLOW_TESTS`: Set this variable to run the slow tests. Default not set.
- `API_TOKEN`: Set this variable if there is already a joplin instance running. **Don't use your default joplin profile!** By default, a joplin instance is started inside xvfb. This takes some time, but works for CI.
## :book: Changelog
### 1.0.0
- Rename the client API. It should be used by `from joppy.client_api import ClientApi` instead of `from joppy.client_api import ClientApi` now.
- Add support for the server API (<https://github.com/marph91/joppy/pull/27>). It should be used by `from joppy.server_api import ServerApi`.
### 0.2.3
- Don't use the root logger for logging.
- Add support for [revisions](https://joplinapp.org/help/api/references/rest_api/#revisions).
### 0.2.2
- Fix adding non-image ressources (<https://github.com/marph91/joppy/issues/24>).
- Cast `markup_language` to an appropriate enum type.
- Add changelog.
### 0.2.1
- Fix PDF output example (<https://github.com/marph91/joppy/issues/19>).
- :warning: Drop tests for python 3.6, since it's EOL. It may still work.
- Fix the type of `todo_completed` and `todo_due`. They are a unix timestamp, not a bool.
### 0.1.1
- Add typing support to the pypi module.
### 0.1.0
- Use a requests session for speedup (<https://github.com/marph91/joppy/issues/15>).
- :warning: Convert the API responses to data objects (<https://github.com/marph91/joppy/pull/17>). Main difference is to use `note.id` instead of `note["id"]` for example.
### 0.0.7
- Fix getting the binary resource file (<https://github.com/marph91/joppy/issues/13>).
### 0.0.6
- Add convenience method for deleting all notes.
- Add example scripts.
### 0.0.5
- Fix package publishing workflow.
### 0.0.4
- Add support for python 3.6 and 3.7.
### 0.0.3
- Fix search with special characters (<https://github.com/marph91/joppy/issues/5>).
- Remove arbitrary arguments from the internal base requests, since they aren't needed and may cause bugs.
### 0.0.2
- CI and test improvements.
- Move complete setup to `setup.cfg`.
### 0.0.1
- Initial release.
Raw data
{
"_id": null,
"home_page": "https://github.com/marph91/joppy",
"name": "joppy",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": null,
"author": "Martin D\u00f6rfelt",
"author_email": "martin.d@andix.de",
"download_url": "https://files.pythonhosted.org/packages/8b/a7/786606efe86ac64b713454b5008550b822310fc42eccedca1c866fa2668c/joppy-1.0.0.tar.gz",
"platform": null,
"description": "# joppy\n\nPython interface for the [Joplin data API](https://joplinapp.org/api/references/rest_api/) (client) and the Joplin server API.\n\n[](https://github.com/marph91/joppy/actions/workflows/build.yml)\n[](https://github.com/marph91/joppy/actions/workflows/lint.yml)\n[](https://github.com/marph91/joppy/actions/workflows/tests.yml)\n[](https://codecov.io/gh/marph91/joppy)\n\n[](https://github.com/laurent22/joplin)\n[](https://pypi.python.org/pypi/joppy/)\n\n## Features\n\n| | Client API Wrapper | Server API Wrapper |\n| --- | --- | --- |\n| **Supported** | All functions from the [data API](https://joplinapp.org/help/api/references/rest_api/) | Some reverse engineered functions with a similar interface like the client API wrapper. See the example below and the source code for details. |\n| **Not Supported** | - | - Encryption <br>- Some functions that were either to complex or I didn't see a use for automation. |\n\n## :computer: Installation\n\nFrom pypi:\n\n```bash\npip install joppy\n```\n\nFrom source:\n\n```bash\ngit clone https://github.com/marph91/joppy.git\ncd joppy\npip install .\n```\n\n## :wrench: Usage\n\nPlease backup your data before use!\n\n### General function description\n\n- `add_<type>()`: Create a new element.\n- `delete_<type>()`: Delete an element by ID.\n- `get_<type>()`: Get an element by ID.\n- `get_all_<type>()`: Get all elements of a kind.\n- `modify_<type>()`: Modify an elements property by ID.\n- `search_all()`: Search elements using [joplins search engine](https://joplinapp.org/api/references/rest_api/#searching).\n\nFor details, consult the [implementation](joppy/api.py), [joplin documentation](https://joplinapp.org/api/references/rest_api/) or [create an issue](https://github.com/marph91/joppy/issues).\n\n## :bulb: Example snippets\n\n### Client API\n\nStart joplin and [get your API token](https://joplinapp.org/api/references/rest_api/#authorisation). Click to expand the examples.\n\n<details>\n<summary>Get all notes</summary>\n\n```python name=get_all_notes\nfrom joppy.client_api import ClientApi\n\n# Create a new Api instance.\napi = ClientApi(token=YOUR_TOKEN)\n\n# Get all notes. Note that this method calls get_notes() multiple times to assemble the unpaginated result.\nnotes = api.get_all_notes()\n```\n\n</details>\n\n<details>\n<summary>Add a tag to a note</summary>\n \n```python name=add_tag_to_note\nfrom joppy.client_api import ClientApi\n\n# Create a new Api instance.\n\napi = ClientApi(token=YOUR_TOKEN)\n\n# Add a notebook.\n\nnotebook_id = api.add_notebook(title=\"My first notebook\")\n\n# Add a note in the previously created notebook.\n\nnote_id = api.add_note(title=\"My first note\", body=\"With some content\", parent_id=notebook_id)\n\n# Add a tag, that is not yet attached to a note.\n\ntag_id = api.add_tag(title=\"introduction\")\n\n# Link the tag to the note.\n\napi.add_tag_to_note(tag_id=tag_id, note_id=note_id)\n\n````\n\n</details>\n\n<details>\n<summary>Add a resource to a note</summary>\n\n```python name=add_resource_to_note\nfrom joppy.client_api import ClientApi\nfrom joppy import tools\n\n# Create a new Api instance.\napi = ClientApi(token=YOUR_TOKEN)\n\n# Add a notebook.\nnotebook_id = api.add_notebook(title=\"My first notebook\")\n\n# Option 1: Add a note with an image data URL. This works only for images.\nimage_data = tools.encode_base64(\"path/to/image.png\")\napi.add_note(\n title=\"My first note\",\n image_data_url=f\"data:image/png;base64,{image_data}\",\n)\n\n# Option 2: Create note and resource separately. Link them later. This works for arbitrary attachments.\nnote_id = api.add_note(title=\"My second note\")\nresource_id = api.add_resource(filename=\"path/to/image.png\", title=\"My first resource\")\napi.add_resource_to_note(resource_id=resource_id, note_id=note_id)\n````\n\n</details>\n\n<details>\n<summary>Bulk remove tags</summary>\n\nInspired by <https://discourse.joplinapp.org/t/bulk-tag-delete-python-script/5497/1>.\n\n```python name=remove_tags\nimport re\n\nfrom joppy.client_api import ClientApi\n\n# Create a new Api instance.\napi = ClientApi(token=YOUR_TOKEN)\n\n# Iterate through all tags.\nfor tag in api.get_all_tags():\n\n # Delete all tags that match the regex. I. e. start with \"!\".\n if re.search(\"^!\", tag.title) is not None:\n api.delete_tag(tag.id)\n```\n\n</details>\n\n<details>\n<summary>Remove unused tags</summary>\n\nReference: <https://discourse.joplinapp.org/t/prune-empty-tags-from-web-clipper/36194>\n\n```python name=remove_unused_tags\nfrom joppy.client_api import ClientApi\n\n# Create a new Api instance.\napi = ClientApi(token=YOUR_TOKEN)\n\nfor tag in api.get_all_tags():\n notes_for_tag = api.get_all_notes(tag_id=tag.id)\n if len(notes_for_tag) == 0:\n print(\"Deleting tag:\", tag.title)\n api.delete_tag(tag.id)\n```\n\n</details>\n\n<details>\n<summary>Remove spaces from tags</summary>\n\nReference: <https://www.reddit.com/r/joplinapp/comments/pozric/batch_remove_spaces_from_all_tags/>\n\n```python name=remove_spaces_from_tags\nimport re\n\nfrom joppy.client_api import ClientApi\n\n# Create a new Api instance.\napi = ClientApi(token=YOUR_TOKEN)\n\n# Define the conversion function.\ndef to_camel_case(name: str) -> str:\n name = re.sub(r\"(_|-)+\", \" \", name).title().replace(\" \", \"\")\n return \"\".join([name[0].lower(), name[1:]])\n\n# Iterate through all tags and apply the conversion.\nfor tag in api.get_all_tags():\n api.modify_tag(id_=tag.id, title=to_camel_case(tag.title))\n```\n\n</details>\n\n<details>\n<summary>Remove orphaned resources</summary>\n\nInspired by <https://discourse.joplinapp.org/t/joplin-vacuum-a-python-script-to-remove-orphaned-resources/19742>.\nNote: The note history is not considered. See: <https://discourse.joplinapp.org/t/joplin-vacuum-a-python-script-to-remove-orphaned-resources/19742/13>.\n\n```python name=remove_orphaned_resources\nimport re\n\nfrom joppy.client_api import ClientApi\n\n# Create a new Api instance.\napi = ClientApi(token=YOUR_TOKEN)\n\n# Getting the referenced resource directly doesn't work:\n# https://github.com/laurent22/joplin/issues/4535\n# So we have to find the referenced resources by regex.\n\n# Iterate through all notes and find the referenced resources.\nreferenced_resources = set()\nfor note in api.get_all_notes(fields=\"id,body\"):\n matches = re.findall(r\"\\[.*\\]\\(:.*\\/([A-Za-z0-9]{32})\\)\", note.body)\n referenced_resources.update(matches)\n\nassert len(referenced_resources) > 0, \"sanity check\"\n\nfor resource in api.get_all_resources():\n if resource.id not in referenced_resources:\n print(\"Deleting resource:\", resource.title)\n api.delete_resource(resource.id)\n```\n\n</details>\n\nFor more usage examples, check the example scripts or [tests](test/test_client_api.py).\n\n### Server API\n\nThe server API should work similarly to the client API in most cases. **Be aware that the server API is experimental and may break at any time. I can't provide any help at sync issues or lost data. Make sure you have a backup and know how to restore it.**\n\n```python\nfrom joppy.server_api import ServerApi\n\n# Create a new Api instance.\napi = ServerApi(user=\"admin@localhost\", password=\"admin\", url=\"http://localhost:22300\")\n\n# Acquire a lock.\nwith api.sync_lock():\n\n # Add a notebook.\n notebook_id = api.add_notebook(title=\"My first notebook\")\n\n # Add a note in the previously created notebook.\n note_id = api.add_note(title=\"My first note\", body=\"With some content\", parent_id=notebook_id)\n```\n\n## :newspaper: Examples\n\nBefore using joppy, you should check the [Joplin plugins](https://joplinapp.org/plugins/). They are probably more convenient. However, if you need a new feature or just want to code in python, you can use joppy.\n\n### Apps\n\n| App | Description |\n| --- | --- |\n| [jimmy](https://github.com/marph91/jimmy) | A tool to import your notes to Joplin |\n| [joplin-sticky-notes](https://github.com/marph91/joplin-sticky-notes) | Stick your Joplin notes to the desktop |\n| [joplin-vieweb](https://github.com/joplin-vieweb/django-joplin-vieweb) | A simple web viewer for Joplin |\n\n### Scripts\n\n| Script | Description |\n| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| [custom_export.py](examples/custom_export.py) | Export resources next to notes, instead of a separate folder. |\n| [note_export.py](examples/note_export.py) | Export notes to any format supported by [pandoc](https://pandoc.org/). |\n| [note_stats.py](examples/note_stats.py) | Get some simple statistics about your notes, based on [nltk](https://www.nltk.org/). |\n| [note_tree_export.py](examples/note_tree_export.py) | Joplin only supports PDF export of a single note. This script allows to export one, multiple or all notebooks to PDF or TXT. |\n| [visualize_note_locations.py](examples/visualize_note_locations.py) | Visualize the locations of your notes. |\n| [joplin-ui-tests](https://github.com/marph91/joplin-ui-tests) | System tests for the joplin desktop app. Based on selenium. |\n\n## :sunny: Tests\n\nTo run the tests, some additional system packages and python modules are needed. After installing them, just run:\n\n```bash\npython -m unittest\n```\n\nIt's possible to configure the test run via some environment variables:\n\n- `SLOW_TESTS`: Set this variable to run the slow tests. Default not set.\n- `API_TOKEN`: Set this variable if there is already a joplin instance running. **Don't use your default joplin profile!** By default, a joplin instance is started inside xvfb. This takes some time, but works for CI.\n\n## :book: Changelog\n\n### 1.0.0\n\n- Rename the client API. It should be used by `from joppy.client_api import ClientApi` instead of `from joppy.client_api import ClientApi` now.\n- Add support for the server API (<https://github.com/marph91/joppy/pull/27>). It should be used by `from joppy.server_api import ServerApi`.\n\n### 0.2.3\n\n- Don't use the root logger for logging.\n- Add support for [revisions](https://joplinapp.org/help/api/references/rest_api/#revisions).\n\n### 0.2.2\n\n- Fix adding non-image ressources (<https://github.com/marph91/joppy/issues/24>).\n- Cast `markup_language` to an appropriate enum type.\n- Add changelog.\n\n### 0.2.1\n\n- Fix PDF output example (<https://github.com/marph91/joppy/issues/19>).\n- :warning: Drop tests for python 3.6, since it's EOL. It may still work.\n- Fix the type of `todo_completed` and `todo_due`. They are a unix timestamp, not a bool.\n\n### 0.1.1\n\n- Add typing support to the pypi module.\n\n### 0.1.0\n\n- Use a requests session for speedup (<https://github.com/marph91/joppy/issues/15>).\n- :warning: Convert the API responses to data objects (<https://github.com/marph91/joppy/pull/17>). Main difference is to use `note.id` instead of `note[\"id\"]` for example.\n\n### 0.0.7\n\n- Fix getting the binary resource file (<https://github.com/marph91/joppy/issues/13>).\n\n### 0.0.6\n\n- Add convenience method for deleting all notes.\n- Add example scripts.\n\n### 0.0.5\n\n- Fix package publishing workflow.\n\n### 0.0.4\n\n- Add support for python 3.6 and 3.7.\n\n### 0.0.3\n\n- Fix search with special characters (<https://github.com/marph91/joppy/issues/5>).\n- Remove arbitrary arguments from the internal base requests, since they aren't needed and may cause bugs.\n\n### 0.0.2\n\n- CI and test improvements.\n- Move complete setup to `setup.cfg`.\n\n### 0.0.1\n\n- Initial release.\n",
"bugtrack_url": null,
"license": "Mozilla Public License version 2.0",
"summary": "Python API for Joplin",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/marph91/joppy"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "78a4068c62731052222cfacea558c705440b37c2c0d8368aa54ffb6269d07b3d",
"md5": "1d4fcb331d80224ba250504f3c95ab69",
"sha256": "98b4091c95aa5195797fb727c4491b9babc013eacde0c1f6d8ac9d695df0f698"
},
"downloads": -1,
"filename": "joppy-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1d4fcb331d80224ba250504f3c95ab69",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 25139,
"upload_time": "2024-09-07T14:46:22",
"upload_time_iso_8601": "2024-09-07T14:46:22.237331Z",
"url": "https://files.pythonhosted.org/packages/78/a4/068c62731052222cfacea558c705440b37c2c0d8368aa54ffb6269d07b3d/joppy-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8ba7786606efe86ac64b713454b5008550b822310fc42eccedca1c866fa2668c",
"md5": "2e9097ad47f02382f20d2513d60d739b",
"sha256": "0b415cde65a04dbe83e4a1ece97babba7f242918017ee920176971d0a6888e2a"
},
"downloads": -1,
"filename": "joppy-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "2e9097ad47f02382f20d2513d60d739b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 36370,
"upload_time": "2024-09-07T14:46:23",
"upload_time_iso_8601": "2024-09-07T14:46:23.553610Z",
"url": "https://files.pythonhosted.org/packages/8b/a7/786606efe86ac64b713454b5008550b822310fc42eccedca1c866fa2668c/joppy-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-07 14:46:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "marph91",
"github_project": "joppy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "joppy"
}