Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
|VersionBadge| |BuildStatus| |CoverageReport| |DocsBuildStatus| |LicenseBadge| |PythonVersions|
.. |VersionBadge| image:: https://badge.fury.io/py/PyOTRS.svg :target: https://badge.fury.io/py/PyOTRS :alt: |version|
.. |BuildStatus| image:: https://gitlab.com/rhab/PyOTRS/badges/main/pipeline.svg :target: https://gitlab.com/rhab/PyOTRS/commits/main :alt: Build Status
.. |CoverageReport| image:: https://gitlab.com/rhab/PyOTRS/badges/main/coverage.svg :target: https://gitlab.com/rhab/PyOTRS/commits/main :alt: Coverage Report
.. |DocsBuildStatus| image:: https://readthedocs.org/projects/pyotrs/badge/?version=stable :target: https://pyotrs.readthedocs.org/en/stable/index.html :alt: Docs Build Status
.. |LicenseBadge| image:: https://img.shields.io/badge/license-MIT-blue.svg :target: https://gitlab.com/rhab/PyOTRS/-/blob/main/LICENSE :alt: MIT licensed
.. |PythonVersions| image:: https://img.shields.io/badge/python-3.7%2C%203.8%2C%203.9%2C%203.10%2C%203.11%2C%203.12-blue.svg :alt: python: 3.8, 3.9, 3.10, 3.11, 3.12
PyOTRS is a Python wrapper for accessing OTRS <https://www.otrs.com/>
_ (Version 6, 7, 8, 2023.1.1) using the
(GenericInterface) REST API.
Please upgrade PyOTRS to at least version 0.10.0 (recommended version is at least 1.0.1) if you
are using OTRS 6.0.27, 7.0.16 or newer. See `issue 27 <https://gitlab.com/rhab/PyOTRS/-/issues/27>`_
and `issue 29 <https://gitlab.com/rhab/PyOTRS/-/issues/29>`_ for more details.
OTRS has introduced a new API in version 8 and with this also changed the API endpoint from
"Session::SessionCreate" to "AccessToken::Create". PyOTRS attempts to use the new API and will
fallback to the old way ("legacy") if the attempt fails.
Access an OTRS instance to::
* create a new Ticket
* get the data of a specific Ticket
* search for Tickets
* update existing Tickets
* access as a "Customer User"
Some of the most notable methods provided are::
* Client.session_create (Use credentials to "log in")
* Client.ticket_create
* Client.ticket_get_by_list (takes a list)
* Client.ticket_get_by_id (takes an int)
* Client.ticket_search
* Client.ticket_update
More details can be found here <pyotrs.html>
_
You have to enable the webservices in your OTRS instance. It is recommended to use the
provided template <https://gitlab.com/rhab/PyOTRS/raw/main/webservices_templates/GenericTicketConnectorREST.yml>
_.
This YAML configuration template includes the Route: /TicketList and SessionGet: /Session/:SessionID endpoint which both are required for PyOTRS but which are not included in the default OTRS webservice setup.
Dependencies are installed automatically
pip::
- python-requests
There also is a (completely optional and rudimentary) interactive CLI which requires click
. This
dependency can be installed by calling pip install PyOTRS[cli]
.
install::
pip install PyOTRS
or consider using a virtual environment::
virtualenv venv
source venv/bin/activate
pip install PyOTRS
Get Ticket with TicketID 1 from OTRS over the REST API::
from pyotrs import Client
client = Client("https://otrs.example.com", "root@localhost", "password")
client.session_create()
client.ticket_get_by_id(1)
The usage of Client.session_restore_or_create
is recommended. It uses a temporary file
on the hard drive to store the Session ID (just like cookies in a browser) and avoids sending
the username+password (and therefore creating a new session) on every API call::
from pyotrs import Client
client = Client("https://otrs.example.com", "root@localhost", "password")
client.session_restore_or_create()
client.ticket_get_by_id(1)
Method Client.session_restore_or_set_up_new
is deprecated as of v0.10 and will be removed in v2.0.
Client
object called clientTicket
with ID 1from pyotrs import Article, Client, DynamicField, Ticket client = Client("http://otrs.example.com", "root@localhost", "password") client.session_create() True
my_ticket = client.ticket_get_by_id(1) my_ticket <Ticket: 1>
my_ticket.field_get("TicketNumber") u'2010080210123456' my_ticket.field_get("Title") u'Welcome to OTRS!' my_ticket.to_dct() # Show complete ticket
from pyotrs import Client client = Client("http://otrs.example.com", "user@customer.example.com", "password", customer_user=True) client.session_create() True
Article
to Ticket
with ID 1my_article = Article({"Subject": "Subj", "Body": "New Body"}) client.ticket_update(1, article=my_article) {u'ArticleID': u'3', u'TicketID': u'1', u'TicketNumber': u'2010080210123456'}
client.ticket_get_by_id(1, articles=1, attachments=1) my_ticket = client.result[0]
my_ticket.articles [<ArticleID: 3>, <ArticleID: 4>
my_ticket.dynamic_fields [<DynamicField: ProcessManagementActivityID: None>, <DynamicField: ProcessManagementProcessID: None>]
client.ticket_get_by_id(1, articles=True, attachments=True, dynamic_fields=True) <Ticket: 1>
client.ticket_get_by_list([1, 3, 4], dynamic_fields=False) [<Ticket: 1>, <Ticket: 3>, <Ticket: 4>]
client.ticket_update(1, Title="New Title") {u'TicketID': u'1', u'TicketNumber': u'2010080210123456'}
client.ticket_update(1, Queue="New Queue") {u'TicketID': u'1', u'TicketNumber': u'2010080210123456'}
client.ticket_update(1, Queue="New Queue", State="closed") {u'TicketID': u'1', u'TicketNumber': u'2010080210123456'}
my_article = Article({"Subject": "Subj", "Body": "New Body"}) client.ticket_update(1, article=my_article) {u'ArticleID': u'3', u'TicketID': u'1', u'TicketNumber': u'2010080210123456'}
att = Attachment.create_from_file("./test_data/asd.txt") client.ticket_update(ticket_id=1, article=my_article, attachments=[att]) {'ArticleID': '7927', 'TicketID': '1', 'TicketNumber': '2010080210123456'}
df = DynamicField("ExternalTicket", "1234") client.ticket_update(1, dynamic_fields=[df]) {u'TicketID': u'1', u'TicketNumber': u'2010080210123456'}
OTRS requires that new Tickets have several fields filled with valid values and that an Article is present for the new Ticket.
new_ticket = Ticket.create_basic(Title="This is the Title", Queue="Raw", State=u"new", Priority=u"3 normal", CustomerUser="root@localhost") first_article = Article({"Subject": "Subj", "Body": "New Body"}) client.ticket_create(new_ticket, first_article) {u'ArticleID': u'9', u'TicketID': u'7', u'TicketNumber': u'2016110528000013'}
PyOTRS defaults to using the MIME type "text/plain". By specifying a different type it is possible to e.g. add a HTML body.
first_article = Article({"Subject": "Subj", "Body": "
This is a header
"
"Link to PyOTRS Docs", "MimeType": "text/html"}) client.ticket_update(10, first_article) {u'ArticleID': u'29', u'TicketID': u'10', u'TicketNumber': u'2017052328000034'}
from datetime import datetime client.ticket_search(TicketCreateTimeOlderDate=datetime(2011, 1, 1)) [u'1']
from datetime import datetime from datetime import timedelta client.ticket_search(TicketCreateTimeNewerDate=datetime.utcnow() - timedelta(days=7)) [u'66', u'65', u'64', u'63']
from datetime import datetime from datetime import timedelta week = datetime.utcnow() - timedelta(days=7) client.ticket_search(TicketCreateTimeOlderDate=week, States=['open', 'new'], QueueIDs=[12])
client.ticket_search(Title="no such ticket") []
df = DynamicField("ExternalTicket", search_patterns=["1234"]) client.ticket_search(dynamic_fields=[df]) [u'2']
df = DynamicField("ExternalTicket", search_patterns=["123*"], search_operator="Like") client.ticket_search([df]) [u'2']
If needed the insecure plattform warnings can be disabled::
# turn off platform insecurity warnings from urllib3
from requests.packages.urllib3 import disable_warnings
disable_warnings() # TODO 2016-04-23 (RH) verify this
The PyOTRS Shell CLI is a kind of "proof-of-concept" for the PyOTRS wrapper library.
Attention: PyOTRS can only retrieve Ticket data at the moment!
Get a Ticket::
pyotrs get -b https://otrs.example.com/ -u root@localhost -p password -t 1
Starting PyOTRS CLI
No config file found at: /home/user/.pyotrs
Connecting to https://otrs.example.com/ as user..
Ticket: Welcome to OTRS!
Queue: Raw
State: closed successful
Priority: 3 normal
Get usage information::
$: pyotrs -h
Usage: PyOTRS [OPTIONS] COMMAND [ARGS]...
Options:
--version Show the version and exit.
--config PATH Config File
-h, --help Show this message and exit.
Commands:
get PyOTRS get command
$:pyotrs get -h
Starting PyOTRS CLI
No config file found at: /home/user/.pyotrs
Usage: PyOTRS get [OPTIONS]
PyOTRS get command
Options:
-b, --baseurl TEXT Base URL
-u, --username TEXT Username
-p, --password TEXT Password
-t, --ticket-id INTEGER Ticket ID
--store-path TEXT where to store Attachments (default:
/tmp/pyotrs_<random_str>
--store-attachments store Article Attachments to
/tmp/<ticket_id>
--attachments include Article Attachments
--articles include Articles
--https-verify / --no-https-verify
HTTPS(SSL/TLS) Certificate validation
(default: enabled)
--ca-cert-bundle TEXT CA CERT Bundle (Path)
-h, --help Show this message and exit.
Get a Ticket "interactively"::
$: pyotrs get
Starting PyOTRS CLI
No config file found at: /home/user/.pyotrs
Baseurl: http://otrs.example.com
Username: user
Password:
Ticket id: 1
Connecting to https://otrs.example.com as user..
Ticket: Welcome to OTRS!
Queue: Raw
State: closed successful
Priority: 3 normal
Full Ticket:
{u'Ticket': {u'TypeID': 1 [...]
There are four ways to provide config values::
1. interactively when prompted
2. as commandline arguments when calling (checkout -h/--help)
3. as settings in the environment
4. in a config file (default location: ~/.pyotrs)
Both the config file and the environment use the same variable names::
PYOTRS_BASEURL=http://otrs.example.com
PYOTRS_USERNAME=root@localhost
PYOTRS_PASSWORD=otrs_password
PYOTRS_HTTPS_VERIFY=True
PYOTRS_CA_CERT_BUNDLE=
MIT License <http://en.wikipedia.org/wiki/MIT_License>
__
FAQs
Python wrapper for OTRS (using REST API)
We found that pyotrs demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.