Name | fa-restsh JSON |
Version |
1.0.0
JSON |
| download |
home_page | None |
Summary | REST and RPC processing, scriptable, shell |
upload_time | 2025-02-22 02:08:59 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.10 |
license | GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public License is intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users. This General Public License applies to most
of the Free Software Foundation's software and to any other program whose
authors commit to using it. (Some other Free Software Foundation software is
covered by the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom to
distribute copies of free software (and charge for this service if you wish),
that you receive source code or can get it if you want it, that you can change
the software or use pieces of it in new free programs; and that you know you can
do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny
you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of the
software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a
fee, you must give the recipients all the rights that you have. You must make
sure that they, too, receive or can get the source code. And you must show them
these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer
you this license which gives you legal permission to copy, distribute and/or
modify the software.
Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If the
software is modified by someone else and passed on, we want its recipients to
know that what they have is not the original, so that any problems introduced by
others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish
to avoid the danger that redistributors of a free program will individually
obtain patent licenses, in effect making the program proprietary. To prevent
this, we have made it clear that any patent must be licensed for everyone's free
use or not licensed at all.
The precise terms and conditions for copying, distribution and modification
follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms of
this General Public License. The "Program", below, refers to any such program or
work, and a "work based on the Program" means either the Program or any
derivative work under copyright law: that is to say, a work containing the
Program or a portion of it, either verbatim or with modifications and/or
translated into another language. (Hereinafter, translation is included without
limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by
this License; they are outside its scope. The act of running the Program is not
restricted, and the output from the Program is covered only if its contents
constitute a work based on the Program (independent of having been made by
running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code as
you receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice and disclaimer of warranty;
keep intact all the notices that refer to this License and to the absence of any
warranty; and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at
your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus
forming a work based on the Program, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all of
these conditions:
a) You must cause the modified files to carry prominent notices stating that
you changed the files and the date of any change. b) You must cause any work
that you distribute or publish, that in whole or in part contains or is derived
from the Program or any part thereof, to be licensed as a whole at no charge to
all third parties under the terms of this License. c) If the modified program
normally reads commands interactively when run, you must cause it, when started
running for such interactive use in the most ordinary way, to print or display
an announcement including an appropriate copyright notice and a notice that
there is no warranty (or else, saying that you provide a warranty) and that
users may redistribute the program under these conditions, and telling the user
how to view a copy of this License. (Exception: if the Program itself is
interactive but does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be reasonably
considered independent and separate works in themselves, then this License, and
its terms, do not apply to those sections when you distribute them as separate
works. But when you distribute the same sections as part of a whole which is a
work based on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the entire whole,
and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise the
right to control the distribution of derivative or collective works based on the
Program.
In addition, mere aggregation of another work not based on the Program with the
Program (or with a work based on the Program) on a volume of a storage or
distribution medium does not bring the other work under the scope of this
License.
3. You may copy and distribute the Program (or a work based on it, under Section
2) in object code or executable form under the terms of Sections 1 and 2 above
provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source
code, which must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange; or, b) Accompany it with a
written offer, valid for at least three years, to give any third party, for a
charge no more than your cost of physically performing source distribution, a
complete machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium customarily
used for software interchange; or, c) Accompany it with the information you
received as to the offer to distribute corresponding source code. (This
alternative is allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such an offer, in
accord with Subsection b above.)
The source code for a work means the preferred form of the work for making
modifications to it. For an executable work, complete source code means all the
source code for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation and installation
of the executable. However, as a special exception, the source code distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.
If distribution of executable or object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the source code
from the same place counts as distribution of the source code, even though third
parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as
expressly provided under this License. Any attempt otherwise to copy, modify,
sublicense or distribute the Program is void, and will automatically terminate
your rights under this License. However, parties who have received copies, or
rights, from you under this License will not have their licenses terminated so
long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it.
However, nothing else grants you permission to modify or distribute the Program
or its derivative works. These actions are prohibited by law if you do not
accept this License. Therefore, by modifying or distributing the Program (or any
work based on the Program), you indicate your acceptance of this License to do
so, and all its terms and conditions for copying, distributing or modifying the
Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program),
the recipient automatically receives a license from the original licensor to
copy, distribute or modify the Program subject to these terms and conditions.
You may not impose any further restrictions on the recipients' exercise of the
rights granted herein. You are not responsible for enforcing compliance by third
parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of this
License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as a
consequence you may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by all those
who receive copies directly or indirectly through you, then the only way you
could satisfy both it and this License would be to refrain entirely from
distribution of the Program.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply and the
section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or
other property right claims or to contest validity of any such claims; this
section has the sole purpose of protecting the integrity of the free software
distribution system, which is implemented by public license practices. Many
people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose that
choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Program under this License may add an explicit
geographical distribution limitation excluding those countries, so that
distribution is permitted only in or among countries not thus excluded. In such
case, this License incorporates the limitation as if written in the body of this
License.
9. The Free Software Foundation may publish revised and/or new versions of the
General Public License from time to time. Such new versions will be similar in
spirit to the present version, but may differ in detail to address new problems
or concerns.
Each version is given a distinguishing version number. If the Program specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Program does not specify a version number of this License, you may choose any
version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For software which is copyrighted by the Free Software Foundation,
write to the Free Software Foundation; we sometimes make exceptions for this.
Our decision will be guided by the two goals of preserving the free status of
all derivatives of our free software and of promoting the sharing and reuse of
software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE
PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED
IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS
IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY
TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND
CONDITIONS
|
keywords |
shell
rest
api
testing
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# About Restsh
Restsh is a shell-like command interpreter for working with RESTful (or REST-esque) remote services.
Often, when you're doing ad-hoc, exploratory, or emergency work with a service like that you're using curl, wget, or GUI interfaces, often in conjunction with some grepping, cutting, and pasting into new requests.
But what if instead, you could treat those service calls like simple functions, and their results and arguments like the data that they *are*?
Enter restsh, combining a shell-like experience for quick and dirty work, and a method for describing how a REST service works (parameter types and so on) so it can be used like a set of functions. This allows you to easily combine, chain, repeat, and script different service calls.
## Sample Session
An example session, using the example outlook service to check emails in an outlook mailbox:
```
REST Shell
Use the "help" command to get help, and "exit" to exit the shell.
$ import outlook
$ help outlook.setAuthentication
outlook.setAuthentication is a function
Replace the authentication data for this service.
It takes 1 arguments:
auth: string
$ outlook.setAuthentication(auth: "eyJ0eXAiOiJKV1Q....")
Service[outlook]
$ let messages = outlook.getMessages(mboxId: "me@example.com")
$ size(of: messages)
6
$ let getSender = \item. item.Sender.EmailAddress.Name
$ let senders = map(arr: messages, fn: getSender)
$ senders
[ "Steven", "Molly", "Mark", "Target", "Louise", "Campaign for Better Times" ]
$ exit
```
## Installation
You can get the latest release from pip:
$ pip install fa-restsh
or from the source:
$ pip install .
## Getting Help
The shell contains a small help system invoked with the `help` command. Use it on its own to see a brief overview of the Restsh session, provide it a value to show information about it. For functions, this includes parameters and their expected types. For objects, this includes each of their properties and their current value types.
Built-in functions and objects, and service objects and methods may include additional information about their use as well.
## But WHY Though?
I hear what you're saying, "This is all written in Python. Can't you just write Python scripts instead?" and yes, you could. And if you're going to be writing anything permanent, you absolutely should.
However, Restsh aims to be a pleasant, helpful environment for when you want to experiment, or need to get something oddly specific done fast.
# Basics
## Types
Restsh supports four simple types:
* strings
* Strings are double quoted, like:
`"Hello World!"`
* Double quotes, newlines, and tabs inside a string can be escaped with a `\`
`"\"Learn programming,\" they said.\n\"It'll be fun,\" they said."`
* integers
* Simple series of digits (in base 10), optionally starting with - or +
`12`
`007`
`-15`
`+32`
* floats
* Like integers, but with a decimal point
`12.5`
`007.0`
`-3.141592`
`+0.1`
* booleans
* True and false:
`true`
`false`
It supports two compound types:
* arrays
* Defined by bracketing a series of values separated by commas
`[1, "two", 3.0]`
* Arrays support subscripts to select specific elements
`myArray[1]`
* objects
* Objects are like dictionaries and are defined by a series of key-value-pairs
`{ color: "red", radius: 12 }`
While array elements and object properties may be modified, neither arrays nor
objects may be extended or shrunk after creation.
## Variables
Variables are declared with `let`, and can be assigned values with `=`.
$ let pi
$ pi = 3.14159
$ let tau = 6.28318
Assignment with `=` is a _statement_ and can only be used at the prompt or the top-level of scripts. To set the value of a variable within a function, for instance, use the `set` function.
$ let foo = 2
$ let setFoo = \to. set(var:foo, value: to)
$ setFoo(to:4)
4
$ foo
4
## Selection (if/then)
The if/then/else expression can be used to make choices.
$ if true then 1 else 2
1
$ if false then 1 else 2
2
$ let f = 2
$ if 2 - f then 1 else 3
3
$ let gg = \v. if v < 4 then "low" else "high"
$ gg(v:3)
low
$ gg(v:6)
high
$
If the `if` part of the expression is "truthy", then the `then` part is evaluated and is the result of the expression. Otherwise, the `else` portion is evaluated as the result.
### Truthiness
The following values are considered "true":
* `true`
* Non-zero integers
* Non-zero floats
* Arrays of non-zero size
* All other values except `null`
Values considered "false":
* `false`
* `0`
* `0.0`
* Arrays of size 0
* `null`
## Functions
Custom functions are defined like this:
\foo, bar. foo + bar
where the above is a function that takes two arguments, `foo` and `bar`, and returns their sum. You might call it like
this:
$ let sum = \foo, bar. foo - bar
$ sum(foo: 5, bar: 3)
2
$ sum(bar: 3, foo: 5)
2
or, with positional arguments:
$ sum(5, 3)
2
Notice that the order of the arguments doesn't matter - just that they're named correctly. Built-in functions and service methods may also have specific type requirements for their arguments.
If you need to do more than one thing in a function, you can chain together expressions with `;`. The final expression will be the result of the function.
$ let accum = 0
$ let bump = \.
. set(var: accum, value: accum + 1);
. print(text: "Accum: " | string(value: accum));
. accum < 4
$ do(fn: bump)
Accum: 1
Accum: 2
Accum: 3
Accum: 4
null
## Handling errors
Most errors cancel execution of a command. However, if it's desirable to ignore an error, a `try` expression can be used to instead return `null` in case of an error.
$ let num = 4
$ let den = 0
$ num / den
error: ZeroDivisionError: division by zero
$ try num / den
error: ZeroDivisionError: division by zero
null
$
## Comments
You can include a comment in a script (or at the prompt if you want) with the `#` character.
# This is a comment
print(text: "Write scripts. Wage wars. Die handsome.") # So is this
# Web Requests
Simple web requests can be made with the `http` object. `http`'s methods all take a complete URL, and return the text response of the request. On a non-2XX or 1XX response, an error is thrown with the status text of the response.
$ http.get(url:"http://www.example.com")
"<html><body><p>This domain is for use in illustrative examples in documents.</p></body></html>"
$
For more complex requests, you will need to define a service.
# Services
Services are the heart of restsh. A service is an object with methods that make restful calls and return their result. Each service is defined by a YAML file. There are several examples included in the "example-services" directory.
A service can be added to the session with the `import` command
$ import msgraph
The `import` command adds the ".yaml" extension to the service name specified to create the filename where the service is defined. To open the file, restsh first looks in the current directory, and then in the ~/.restsh directory.
After a service is imported, a new object with the service's name as added to the session. That object has a method for each call defined in its YAML file, plus the following predefined methods:
* `setHost(host)` - Replaces the host and port defined in the service definition
* `setAuthentication(auth)` - Sets or replaces the authentication data of the service. This persists between calls, but is only used if the authentication type is set in the service definition.
NOTE: A service may be *reimported*, in which case its yaml description is reevulated, allowing you to make changes or add new calls during a session. Changes to the host or authentication will be reset.
## Defining Services
Service definitions are layed out as follows:
---
protocol: http|https|amqp
host: host & port
description: displayed by the help command
authentication:
type: basic|bearer|cookie|etc
data: auth data string
call:
- name: method name
description: displayed by the help command
timeout: call timeout in seconds; 60 second default
params:
method-param1: data type
method-param2: data type
headers:
protocol-header-1: value
protocol-header-2: value
body: text of the request body, if any
response:
type: json|text
transform: restsh code
error: restsh code
# For http and https protocols:
path: path portion of the URL
query: query string portion of the URL
fragment: hash string portion of the URL
At the top-level, only `protocol`, `host`, and `call` are required. If the `authentication` section is omitted, no authentication will be done, even if you later call `setAuthentication` on the service object.
The `call` section is a list of service call definitions. Here, only the `name` property of a call is truly required.
The `params` section is a list of parameter names and types. The parameter names will be used for the service method's parameters, and as template variables for the text attributes of the call definition.
The `body` section is text that will be sent as the data of the request.
For `http` and `https` requests, `path`, `query`, and `fragment` are combined with the `host` to create the URL to connect to.
The `response` section defines how to handle the service response. By default the full text of th response is returned as a string, but the `type` can be set to `json` parse the response as JSON instead. The `transform` section allows you to specify a restsh command whose result replaces the default response object as the call method's result. Similarly, the `error` section is a restsh command whose result, if `true`, causes the call method to throw an error rather than return a result.
## Authentication Data
The authentication `data` field is the actual authentication token etc. that is passed to the service, so it can (and probably should) be omitted from the service file and instead set during a restsh session with `setAuthentication`.
For `basic` authentication, the user name and password should both be provided, separated by a `:`.
Similarly, for `cookie` authentication, the cookie name and value should be provided, also separated by a `:`.
The `http` and `https` protocols allowed any other arbitrary `type` to be specified. The specified type (`bearer` for instance) will be used as the "scheme" of the HTTP `authorization` header, and the authentication data will be provided verbatim as the credentials.
The `amqp` protocol only supports `basic` authentication.
## Parameter Data Types
The following type names map directly to types described above:
* string
* integer
* float
* boolean
* array
* object
* function
In addition, the following meta types meta-types can be used:
* any
* Any value at all
* number
* Either an integer or a float
* collection
* Either an array or an object
The array, collection, object, and function types may be specified with further descriptors in brackets, such as `array[integer]` to denote an array of integers. These descriptors are only informational and not currently enforced by the type checker.
## Text Templates
The following call attributes allow for template variables:
* headers
* body
* path
* query
* fragment
Template variables are specified in text by surrounding any of the named call parameters in `$` characters. (To include a `$` in the text directly use `$$`.) The value of corresponding method argument will replace the template variable.
Take the following call definition on a service called `userprofile`:
name: setDescription
path: /profile
method: PATCH
params:
text: string
body: |
{ "description": "$text$"
}
This would be called from the shell like
$ import userprofile
$ userprofile.setDescription(text: "I love cats and rombic solids")
"updated!"
$
This call would send a PATCH request with the body
{ "description": "I love cats and rombic solids"
}
## Response Section
### type
The `type` attribute can be either `text`, in which case the response will be a string that is the entire response body, or `json` in which case the result will be parsed as JSON and the response type will depend on the content of the response itself.
### transform
The `transform` attribute is a restsh command. Within the transform command, every top level variable, function, and operator is available for use. In addition, the variable `response` is defined, containing the default service call response (dependant on the specified `type`).
Services using the `http` and `https` protocols additionally provide `status`, containing the HTTP status code of the response, and `headers` an object containing the response headers.
### error
The `error` attribute functions much the same as the `transform` attribute. However, the `error` command must return either `true`, if the response should be considered failed, or `false` if it was successful.
## AMQP Support
Restsh uses the amqp package for AMQP 0-9 support. However, it is not a hard
requirement. If you want to define AMQP-based services, you will need to
pip-install amqp separately.
Services using the `amqp` protocol only supports `basic` authentication (or none).
Header values for AMQP calls may be integers and floats in addition to strings.
# Scripting
On startup, restsh will look for a file named `~/.restshrc` and run all of the commands there before the first prompt. Additionally, you can direct restsh to run other script files before first prompt with the `--environment` command-line argument.
If other files are provided on the command-line, they will be run in order and then the interpreter will exit. This can be combined with `--environment` arguments.
## Standalone Scripts
While in general you probably want to use something like Python for standalone scripts, you can create Restsh scripts similarly to shell scripts:
$ cat > runme <<END
#!/usr/local/bin/restsh
print(text: "You ran me!")
END
$ chmod u+x runme
$ ./runme
You ran me!
$
Arguments passed to the script on the command line are stored as an array of strings in the `args` top-level variable.
# Sessions
You can save and load the current state of the shell with the `session` object.
To save the current session, use `session.save`, like so:
$ import weatherapi
$ let data = weatherapi.today()
$ let tempF = data.temp * 1.8 + 32
$ session.save(name: "weather")
Our two variables, `data` and `tempF`, and the fact that we imported weatherapi are saved in a session named "weather" (and "weather" becomes the default session).
We can reload this session with `session.open`:
$ session.open(name: "weather")
$ print(text: "Temperature: " | string(value: tempF) | "F")
Temperature: 45F
When a session is saved or opened it becomes the `current` session, and future calls to `save` will save to that session by default.
$ session.open(name: "weather")
$ let precip = data.precipitation
$ session.save()
By default, the current session name is the empty string.
Additionally, you can clear the current session using `session.clear`:
$ session.open(name: "weather")
$ print(text: precip)
Light Rain
$ session.clear()
$ print(text: string(value: tempF))
error: Undefined variable: 'tempF'
The session management isn't perfect, but it should do the right thing most of the time.
# Copyright
REST Shell is copyright 2024 Raymond W. Wallace III
You may copy or modify it under the terms of the [GNU Public License version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
Raw data
{
"_id": null,
"home_page": null,
"name": "fa-restsh",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "shell, REST, API, testing",
"author": null,
"author_email": "Ray Wallace III <rwallace3@proton.me>",
"download_url": null,
"platform": null,
"description": "# About Restsh\n\nRestsh is a shell-like command interpreter for working with RESTful (or REST-esque) remote services.\n\nOften, when you're doing ad-hoc, exploratory, or emergency work with a service like that you're using curl, wget, or GUI interfaces, often in conjunction with some grepping, cutting, and pasting into new requests.\n\nBut what if instead, you could treat those service calls like simple functions, and their results and arguments like the data that they *are*?\n\nEnter restsh, combining a shell-like experience for quick and dirty work, and a method for describing how a REST service works (parameter types and so on) so it can be used like a set of functions. This allows you to easily combine, chain, repeat, and script different service calls.\n\n\n## Sample Session\n\nAn example session, using the example outlook service to check emails in an outlook mailbox:\n\n```\nREST Shell \n \nUse the \"help\" command to get help, and \"exit\" to exit the shell. \n$ import outlook\n$ help outlook.setAuthentication\noutlook.setAuthentication is a function \n \nReplace the authentication data for this service. \n\nIt takes 1 arguments: \n auth: string \n \n$ outlook.setAuthentication(auth: \"eyJ0eXAiOiJKV1Q....\")\nService[outlook]\n$ let messages = outlook.getMessages(mboxId: \"me@example.com\")\n$ size(of: messages)\n6\n$ let getSender = \\item. item.Sender.EmailAddress.Name\n$ let senders = map(arr: messages, fn: getSender)\n$ senders\n[ \"Steven\", \"Molly\", \"Mark\", \"Target\", \"Louise\", \"Campaign for Better Times\" ]\n$ exit\n```\n\n## Installation\n\nYou can get the latest release from pip:\n\n $ pip install fa-restsh\n\nor from the source:\n\n $ pip install .\n\n\n## Getting Help\n\nThe shell contains a small help system invoked with the `help` command. Use it on its own to see a brief overview of the Restsh session, provide it a value to show information about it. For functions, this includes parameters and their expected types. For objects, this includes each of their properties and their current value types.\n\nBuilt-in functions and objects, and service objects and methods may include additional information about their use as well.\n\n## But WHY Though?\n\nI hear what you're saying, \"This is all written in Python. Can't you just write Python scripts instead?\" and yes, you could. And if you're going to be writing anything permanent, you absolutely should.\n\nHowever, Restsh aims to be a pleasant, helpful environment for when you want to experiment, or need to get something oddly specific done fast.\n\n# Basics\n\n## Types\n\nRestsh supports four simple types:\n\n* strings\n\n\t* Strings are double quoted, like:\n\t\n\t\t`\"Hello World!\"`\n\t\n\t* Double quotes, newlines, and tabs inside a string can be escaped with a `\\`\n\t\n\t\t`\"\\\"Learn programming,\\\" they said.\\n\\\"It'll be fun,\\\" they said.\"`\n\n* integers\n\n\t* Simple series of digits (in base 10), optionally starting with - or +\n\n\t\t`12`\n\n\t\t`007`\n\n\t\t`-15`\n\n\t\t`+32`\n\n* floats\n\t\n\t* Like integers, but with a decimal point\n\t\n\t\t`12.5`\n\n\t\t`007.0`\n\n\t\t`-3.141592`\n\n\t\t`+0.1`\n\n* booleans\n\n\t* True and false:\n\t\n\t\t`true`\n\n\t\t`false`\n\nIt supports two compound types:\n\n* arrays\n\n\t* Defined by bracketing a series of values separated by commas\n\t\n\t\t`[1, \"two\", 3.0]`\n\n\t* Arrays support subscripts to select specific elements\n\t\n\t\t`myArray[1]`\n\n* objects\n\n\t* Objects are like dictionaries and are defined by a series of key-value-pairs\n\t\n\t\t`{ color: \"red\", radius: 12 }`\n\nWhile array elements and object properties may be modified, neither arrays nor\nobjects may be extended or shrunk after creation.\n\n## Variables\n\nVariables are declared with `let`, and can be assigned values with `=`.\n\n\t$ let pi\n\t$ pi = 3.14159 \n\t$ let tau = 6.28318\n\nAssignment with `=` is a _statement_ and can only be used at the prompt or the top-level of scripts. To set the value of a variable within a function, for instance, use the `set` function.\n\n\t$ let foo = 2\n\t$ let setFoo = \\to. set(var:foo, value: to)\n\t$ setFoo(to:4)\n\t4\n\t$ foo\n\t4\n\n## Selection (if/then)\n\nThe if/then/else expression can be used to make choices.\n\n\t$ if true then 1 else 2\n\t1\n\t$ if false then 1 else 2\n\t2\n\t$ let f = 2\n\t$ if 2 - f then 1 else 3\n\t3\n\t$ let gg = \\v. if v < 4 then \"low\" else \"high\"\n\t$ gg(v:3)\n\tlow\n\t$ gg(v:6)\n\thigh\n\t$ \n\nIf the `if` part of the expression is \"truthy\", then the `then` part is evaluated and is the result of the expression. Otherwise, the `else` portion is evaluated as the result.\n\n### Truthiness\n\nThe following values are considered \"true\":\n\n* `true`\n\n* Non-zero integers\n\n* Non-zero floats\n\n* Arrays of non-zero size\n\n* All other values except `null`\n\nValues considered \"false\":\n\n* `false`\n\n* `0`\n\n* `0.0`\n\n* Arrays of size 0\n\n* `null`\n\n\n## Functions\n\nCustom functions are defined like this:\n\n\t\\foo, bar. foo + bar\n\nwhere the above is a function that takes two arguments, `foo` and `bar`, and returns their sum. You might call it like\nthis:\n\n\t$ let sum = \\foo, bar. foo - bar\n\t$ sum(foo: 5, bar: 3)\n\t2\n\t$ sum(bar: 3, foo: 5)\n\t2\n\nor, with positional arguments:\n\n\t$ sum(5, 3)\n\t2\n\nNotice that the order of the arguments doesn't matter - just that they're named correctly. Built-in functions and service methods may also have specific type requirements for their arguments.\n\nIf you need to do more than one thing in a function, you can chain together expressions with `;`. The final expression will be the result of the function.\n\n\t$ let accum = 0\n\t$ let bump = \\.\n\t. set(var: accum, value: accum + 1);\n\t. print(text: \"Accum: \" | string(value: accum));\n\t. accum < 4\n\t$ do(fn: bump)\n\tAccum: 1\n\tAccum: 2\n\tAccum: 3\n\tAccum: 4\n\tnull\n\n## Handling errors\n\nMost errors cancel execution of a command. However, if it's desirable to ignore an error, a `try` expression can be used to instead return `null` in case of an error.\n\n\t$ let num = 4\n\t$ let den = 0\n\t$ num / den\n\terror: ZeroDivisionError: division by zero\n\t$ try num / den\n\terror: ZeroDivisionError: division by zero\n\tnull\n\t$ \n\n## Comments\n\nYou can include a comment in a script (or at the prompt if you want) with the `#` character.\n\n\t# This is a comment\n\tprint(text: \"Write scripts. Wage wars. Die handsome.\") # So is this\n\n# Web Requests\n\nSimple web requests can be made with the `http` object. `http`'s methods all take a complete URL, and return the text response of the request. On a non-2XX or 1XX response, an error is thrown with the status text of the response.\n\n\t$ http.get(url:\"http://www.example.com\")\n\t\"<html><body><p>This domain is for use in illustrative examples in documents.</p></body></html>\"\n\t$ \n\nFor more complex requests, you will need to define a service.\n\n# Services\n\nServices are the heart of restsh. A service is an object with methods that make restful calls and return their result. Each service is defined by a YAML file. There are several examples included in the \"example-services\" directory.\n\nA service can be added to the session with the `import` command\n\n\t$ import msgraph\n\nThe `import` command adds the \".yaml\" extension to the service name specified to create the filename where the service is defined. To open the file, restsh first looks in the current directory, and then in the ~/.restsh directory.\n\nAfter a service is imported, a new object with the service's name as added to the session. That object has a method for each call defined in its YAML file, plus the following predefined methods:\n\n* `setHost(host)` - Replaces the host and port defined in the service definition\n\n* `setAuthentication(auth)` - Sets or replaces the authentication data of the service. This persists between calls, but is only used if the authentication type is set in the service definition.\n\nNOTE: A service may be *reimported*, in which case its yaml description is reevulated, allowing you to make changes or add new calls during a session. Changes to the host or authentication will be reset.\n\n\n## Defining Services\n\nService definitions are layed out as follows:\n\n\t---\n\tprotocol: http|https|amqp\n\thost: host & port\n\tdescription: displayed by the help command\n\tauthentication:\n\t type: basic|bearer|cookie|etc\n\t data: auth data string\n\tcall:\n\t - name: method name\n\t description: displayed by the help command\n\t timeout: call timeout in seconds; 60 second default\n\t params:\n\t method-param1: data type\n\t method-param2: data type\n\t headers:\n\t protocol-header-1: value \n\t protocol-header-2: value \n\t body: text of the request body, if any\n\t response:\n\t type: json|text\n\t transform: restsh code\n\t error: restsh code\n\t # For http and https protocols:\n\t path: path portion of the URL\n\t query: query string portion of the URL\t \n\t fragment: hash string portion of the URL\n\nAt the top-level, only `protocol`, `host`, and `call` are required. If the `authentication` section is omitted, no authentication will be done, even if you later call `setAuthentication` on the service object.\n\nThe `call` section is a list of service call definitions. Here, only the `name` property of a call is truly required.\n\nThe `params` section is a list of parameter names and types. The parameter names will be used for the service method's parameters, and as template variables for the text attributes of the call definition.\n\nThe `body` section is text that will be sent as the data of the request.\n\nFor `http` and `https` requests, `path`, `query`, and `fragment` are combined with the `host` to create the URL to connect to.\n\nThe `response` section defines how to handle the service response. By default the full text of th response is returned as a string, but the `type` can be set to `json` parse the response as JSON instead. The `transform` section allows you to specify a restsh command whose result replaces the default response object as the call method's result. Similarly, the `error` section is a restsh command whose result, if `true`, causes the call method to throw an error rather than return a result.\n\n## Authentication Data\n\nThe authentication `data` field is the actual authentication token etc. that is passed to the service, so it can (and probably should) be omitted from the service file and instead set during a restsh session with `setAuthentication`.\n\nFor `basic` authentication, the user name and password should both be provided, separated by a `:`.\n\nSimilarly, for `cookie` authentication, the cookie name and value should be provided, also separated by a `:`.\n\nThe `http` and `https` protocols allowed any other arbitrary `type` to be specified. The specified type (`bearer` for instance) will be used as the \"scheme\" of the HTTP `authorization` header, and the authentication data will be provided verbatim as the credentials.\n\nThe `amqp` protocol only supports `basic` authentication.\n\n## Parameter Data Types\n\nThe following type names map directly to types described above:\n\n* string\n* integer\n* float\n* boolean\n* array\n* object\n* function\n\nIn addition, the following meta types meta-types can be used:\n\n* any\n * Any value at all\n* number\n * Either an integer or a float\n* collection\n * Either an array or an object\n\nThe array, collection, object, and function types may be specified with further descriptors in brackets, such as `array[integer]` to denote an array of integers. These descriptors are only informational and not currently enforced by the type checker.\n\n## Text Templates\n\nThe following call attributes allow for template variables:\n\n* headers\n* body\n* path\n* query\n* fragment\n\nTemplate variables are specified in text by surrounding any of the named call parameters in `$` characters. (To include a `$` in the text directly use `$$`.) The value of corresponding method argument will replace the template variable.\n\nTake the following call definition on a service called `userprofile`:\n\n\tname: setDescription\n\tpath: /profile\n\tmethod: PATCH\n\tparams:\n\t text: string\n\tbody: |\n\t { \"description\": \"$text$\"\n\t }\n\nThis would be called from the shell like\n\n\t$ import userprofile\n\t$ userprofile.setDescription(text: \"I love cats and rombic solids\")\n\t\"updated!\"\n\t$\n\nThis call would send a PATCH request with the body\n\n\t{ \"description\": \"I love cats and rombic solids\"\n\t}\n\n## Response Section\n\n### type\n\nThe `type` attribute can be either `text`, in which case the response will be a string that is the entire response body, or `json` in which case the result will be parsed as JSON and the response type will depend on the content of the response itself.\n\n### transform\n\nThe `transform` attribute is a restsh command. Within the transform command, every top level variable, function, and operator is available for use. In addition, the variable `response` is defined, containing the default service call response (dependant on the specified `type`).\n\nServices using the `http` and `https` protocols additionally provide `status`, containing the HTTP status code of the response, and `headers` an object containing the response headers.\n\n### error\n\nThe `error` attribute functions much the same as the `transform` attribute. However, the `error` command must return either `true`, if the response should be considered failed, or `false` if it was successful.\n\n## AMQP Support\n\nRestsh uses the amqp package for AMQP 0-9 support. However, it is not a hard\nrequirement. If you want to define AMQP-based services, you will need to\npip-install amqp separately.\n\nServices using the `amqp` protocol only supports `basic` authentication (or none).\n\nHeader values for AMQP calls may be integers and floats in addition to strings.\n\n# Scripting\n\nOn startup, restsh will look for a file named `~/.restshrc` and run all of the commands there before the first prompt. Additionally, you can direct restsh to run other script files before first prompt with the `--environment` command-line argument.\n\nIf other files are provided on the command-line, they will be run in order and then the interpreter will exit. This can be combined with `--environment` arguments.\n\n## Standalone Scripts\n\nWhile in general you probably want to use something like Python for standalone scripts, you can create Restsh scripts similarly to shell scripts:\n\n\t$ cat > runme <<END\n\t#!/usr/local/bin/restsh\n\n\tprint(text: \"You ran me!\")\n\tEND\n\t$ chmod u+x runme\n\t$ ./runme\n\tYou ran me!\n\t$\n\nArguments passed to the script on the command line are stored as an array of strings in the `args` top-level variable.\n\n# Sessions\n\nYou can save and load the current state of the shell with the `session` object.\n\nTo save the current session, use `session.save`, like so:\n\n\t$ import weatherapi\n\t$ let data = weatherapi.today()\n\t$ let tempF = data.temp * 1.8 + 32\n\t$ session.save(name: \"weather\")\n\nOur two variables, `data` and `tempF`, and the fact that we imported weatherapi are saved in a session named \"weather\" (and \"weather\" becomes the default session).\n\nWe can reload this session with `session.open`:\n\n\t$ session.open(name: \"weather\")\n\t$ print(text: \"Temperature: \" | string(value: tempF) | \"F\")\n\tTemperature: 45F\n\nWhen a session is saved or opened it becomes the `current` session, and future calls to `save` will save to that session by default.\n\n\t$ session.open(name: \"weather\")\n\t$ let precip = data.precipitation\n\t$ session.save()\n\nBy default, the current session name is the empty string.\n\nAdditionally, you can clear the current session using `session.clear`:\n\n\t$ session.open(name: \"weather\")\n\t$ print(text: precip)\n\tLight Rain\n\t$ session.clear()\n\t$ print(text: string(value: tempF))\n\terror: Undefined variable: 'tempF'\n\nThe session management isn't perfect, but it should do the right thing most of the time.\n\n# Copyright\n\nREST Shell is copyright 2024 Raymond W. Wallace III\n\nYou may copy or modify it under the terms of the [GNU Public License version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).\n\n\n",
"bugtrack_url": null,
"license": "GNU GENERAL PUBLIC LICENSE\n \n Version 2, June 1991\n \n Copyright (C) 1989, 1991 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies of this license\n document, but changing it is not allowed.\n \n Preamble\n \n The licenses for most software are designed to take away your freedom to share\n and change it. By contrast, the GNU General Public License is intended to\n guarantee your freedom to share and change free software--to make sure the\n software is free for all its users. This General Public License applies to most\n of the Free Software Foundation's software and to any other program whose\n authors commit to using it. (Some other Free Software Foundation software is\n covered by the GNU Lesser General Public License instead.) You can apply it to\n your programs, too.\n \n When we speak of free software, we are referring to freedom, not price. Our\n General Public Licenses are designed to make sure that you have the freedom to\n distribute copies of free software (and charge for this service if you wish),\n that you receive source code or can get it if you want it, that you can change\n the software or use pieces of it in new free programs; and that you know you can\n do these things.\n \n To protect your rights, we need to make restrictions that forbid anyone to deny\n you these rights or to ask you to surrender the rights. These restrictions\n translate to certain responsibilities for you if you distribute copies of the\n software, or if you modify it.\n \n For example, if you distribute copies of such a program, whether gratis or for a\n fee, you must give the recipients all the rights that you have. You must make\n sure that they, too, receive or can get the source code. And you must show them\n these terms so they know their rights.\n \n We protect your rights with two steps: (1) copyright the software, and (2) offer\n you this license which gives you legal permission to copy, distribute and/or\n modify the software.\n \n Also, for each author's protection and ours, we want to make certain that\n everyone understands that there is no warranty for this free software. If the\n software is modified by someone else and passed on, we want its recipients to\n know that what they have is not the original, so that any problems introduced by\n others will not reflect on the original authors' reputations.\n \n Finally, any free program is threatened constantly by software patents. We wish\n to avoid the danger that redistributors of a free program will individually\n obtain patent licenses, in effect making the program proprietary. To prevent\n this, we have made it clear that any patent must be licensed for everyone's free\n use or not licensed at all.\n \n The precise terms and conditions for copying, distribution and modification\n follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n \n 0. This License applies to any program or other work which contains a notice\n placed by the copyright holder saying it may be distributed under the terms of\n this General Public License. The \"Program\", below, refers to any such program or\n work, and a \"work based on the Program\" means either the Program or any\n derivative work under copyright law: that is to say, a work containing the\n Program or a portion of it, either verbatim or with modifications and/or\n translated into another language. (Hereinafter, translation is included without\n limitation in the term \"modification\".) Each licensee is addressed as \"you\".\n \n Activities other than copying, distribution and modification are not covered by\n this License; they are outside its scope. The act of running the Program is not\n restricted, and the output from the Program is covered only if its contents\n constitute a work based on the Program (independent of having been made by\n running the Program). Whether that is true depends on what the Program does.\n \n 1. You may copy and distribute verbatim copies of the Program's source code as\n you receive it, in any medium, provided that you conspicuously and appropriately\n publish on each copy an appropriate copyright notice and disclaimer of warranty;\n keep intact all the notices that refer to this License and to the absence of any\n warranty; and give any other recipients of the Program a copy of this License\n along with the Program.\n \n You may charge a fee for the physical act of transferring a copy, and you may at\n your option offer warranty protection in exchange for a fee.\n \n 2. You may modify your copy or copies of the Program or any portion of it, thus\n forming a work based on the Program, and copy and distribute such modifications\n or work under the terms of Section 1 above, provided that you also meet all of\n these conditions:\n \n a) You must cause the modified files to carry prominent notices stating that\n you changed the files and the date of any change. b) You must cause any work\n that you distribute or publish, that in whole or in part contains or is derived\n from the Program or any part thereof, to be licensed as a whole at no charge to\n all third parties under the terms of this License. c) If the modified program\n normally reads commands interactively when run, you must cause it, when started\n running for such interactive use in the most ordinary way, to print or display\n an announcement including an appropriate copyright notice and a notice that\n there is no warranty (or else, saying that you provide a warranty) and that\n users may redistribute the program under these conditions, and telling the user\n how to view a copy of this License. (Exception: if the Program itself is\n interactive but does not normally print such an announcement, your work based on\n the Program is not required to print an announcement.) \n \n These requirements apply to the modified work as a whole. If identifiable\n sections of that work are not derived from the Program, and can be reasonably\n considered independent and separate works in themselves, then this License, and\n its terms, do not apply to those sections when you distribute them as separate\n works. But when you distribute the same sections as part of a whole which is a\n work based on the Program, the distribution of the whole must be on the terms of\n this License, whose permissions for other licensees extend to the entire whole,\n and thus to each and every part regardless of who wrote it.\n \n Thus, it is not the intent of this section to claim rights or contest your\n rights to work written entirely by you; rather, the intent is to exercise the\n right to control the distribution of derivative or collective works based on the\n Program.\n \n In addition, mere aggregation of another work not based on the Program with the\n Program (or with a work based on the Program) on a volume of a storage or\n distribution medium does not bring the other work under the scope of this\n License.\n \n 3. You may copy and distribute the Program (or a work based on it, under Section\n 2) in object code or executable form under the terms of Sections 1 and 2 above\n provided that you also do one of the following:\n \n a) Accompany it with the complete corresponding machine-readable source\n code, which must be distributed under the terms of Sections 1 and 2 above on a\n medium customarily used for software interchange; or, b) Accompany it with a\n written offer, valid for at least three years, to give any third party, for a\n charge no more than your cost of physically performing source distribution, a\n complete machine-readable copy of the corresponding source code, to be\n distributed under the terms of Sections 1 and 2 above on a medium customarily\n used for software interchange; or, c) Accompany it with the information you\n received as to the offer to distribute corresponding source code. (This\n alternative is allowed only for noncommercial distribution and only if you\n received the program in object code or executable form with such an offer, in\n accord with Subsection b above.) \n \n The source code for a work means the preferred form of the work for making\n modifications to it. For an executable work, complete source code means all the\n source code for all modules it contains, plus any associated interface\n definition files, plus the scripts used to control compilation and installation\n of the executable. However, as a special exception, the source code distributed\n need not include anything that is normally distributed (in either source or\n binary form) with the major components (compiler, kernel, and so on) of the\n operating system on which the executable runs, unless that component itself\n accompanies the executable.\n \n If distribution of executable or object code is made by offering access to copy\n from a designated place, then offering equivalent access to copy the source code\n from the same place counts as distribution of the source code, even though third\n parties are not compelled to copy the source along with the object code.\n \n 4. You may not copy, modify, sublicense, or distribute the Program except as\n expressly provided under this License. Any attempt otherwise to copy, modify,\n sublicense or distribute the Program is void, and will automatically terminate\n your rights under this License. However, parties who have received copies, or\n rights, from you under this License will not have their licenses terminated so\n long as such parties remain in full compliance.\n \n 5. You are not required to accept this License, since you have not signed it.\n However, nothing else grants you permission to modify or distribute the Program\n or its derivative works. These actions are prohibited by law if you do not\n accept this License. Therefore, by modifying or distributing the Program (or any\n work based on the Program), you indicate your acceptance of this License to do\n so, and all its terms and conditions for copying, distributing or modifying the\n Program or works based on it.\n \n 6. Each time you redistribute the Program (or any work based on the Program),\n the recipient automatically receives a license from the original licensor to\n copy, distribute or modify the Program subject to these terms and conditions.\n You may not impose any further restrictions on the recipients' exercise of the\n rights granted herein. You are not responsible for enforcing compliance by third\n parties to this License.\n \n 7. If, as a consequence of a court judgment or allegation of patent infringement\n or for any other reason (not limited to patent issues), conditions are imposed\n on you (whether by court order, agreement or otherwise) that contradict the\n conditions of this License, they do not excuse you from the conditions of this\n License. If you cannot distribute so as to satisfy simultaneously your\n obligations under this License and any other pertinent obligations, then as a\n consequence you may not distribute the Program at all. For example, if a patent\n license would not permit royalty-free redistribution of the Program by all those\n who receive copies directly or indirectly through you, then the only way you\n could satisfy both it and this License would be to refrain entirely from\n distribution of the Program.\n \n If any portion of this section is held invalid or unenforceable under any\n particular circumstance, the balance of the section is intended to apply and the\n section as a whole is intended to apply in other circumstances.\n \n It is not the purpose of this section to induce you to infringe any patents or\n other property right claims or to contest validity of any such claims; this\n section has the sole purpose of protecting the integrity of the free software\n distribution system, which is implemented by public license practices. Many\n people have made generous contributions to the wide range of software\n distributed through that system in reliance on consistent application of that\n system; it is up to the author/donor to decide if he or she is willing to\n distribute software through any other system and a licensee cannot impose that\n choice.\n \n This section is intended to make thoroughly clear what is believed to be a\n consequence of the rest of this License.\n \n 8. If the distribution and/or use of the Program is restricted in certain\n countries either by patents or by copyrighted interfaces, the original copyright\n holder who places the Program under this License may add an explicit\n geographical distribution limitation excluding those countries, so that\n distribution is permitted only in or among countries not thus excluded. In such\n case, this License incorporates the limitation as if written in the body of this\n License.\n \n 9. The Free Software Foundation may publish revised and/or new versions of the\n General Public License from time to time. Such new versions will be similar in\n spirit to the present version, but may differ in detail to address new problems\n or concerns.\n \n Each version is given a distinguishing version number. If the Program specifies\n a version number of this License which applies to it and \"any later version\",\n you have the option of following the terms and conditions either of that version\n or of any later version published by the Free Software Foundation. If the\n Program does not specify a version number of this License, you may choose any\n version ever published by the Free Software Foundation.\n \n 10. If you wish to incorporate parts of the Program into other free programs\n whose distribution conditions are different, write to the author to ask for\n permission. For software which is copyrighted by the Free Software Foundation,\n write to the Free Software Foundation; we sometimes make exceptions for this.\n Our decision will be guided by the two goals of preserving the free status of\n all derivatives of our free software and of promoting the sharing and reuse of\n software generally.\n \n NO WARRANTY\n \n 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE\n PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED\n IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS\n IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT\n NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\n PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\n ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n \n 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL\n ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE\n PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,\n SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY\n TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\n RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF\n THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER\n PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND\n CONDITIONS\n ",
"summary": "REST and RPC processing, scriptable, shell",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/faboo/restsh",
"Repository": "https://github.com/faboo/restsh.git"
},
"split_keywords": [
"shell",
" rest",
" api",
" testing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "816247b53f0f74dd481bef6279647102785b6c8d0260a172d36c030dcb3e0301",
"md5": "731d8bff44612093df4062d0c9f4e303",
"sha256": "5998be8c857711cdc8cf4c3f68d9ae360a5d087c2526fa6cc2da9844842e444e"
},
"downloads": -1,
"filename": "fa_restsh-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "731d8bff44612093df4062d0c9f4e303",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 49129,
"upload_time": "2025-02-22T02:08:59",
"upload_time_iso_8601": "2025-02-22T02:08:59.756917Z",
"url": "https://files.pythonhosted.org/packages/81/62/47b53f0f74dd481bef6279647102785b6c8d0260a172d36c030dcb3e0301/fa_restsh-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-22 02:08:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "faboo",
"github_project": "restsh",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "fa-restsh"
}