Twisted REST micro-framework
Based on Flask API, with plans for integrated multiprocessing support for full usage of all CPUs. Provides a more Flask/Sinatra-style API on top of the core twisted.web APIs. Integrates FormEncode for path, form and query argument validation.
An example of a multi–module twisted.web CorePost REST application which exposes two separate REST services (for a Customer and Customer Address entities):
class CustomerRESTService():
path = "/customer"
@route("/")
def getAll(self,request):
return DB.getAllCustomers()
@route("/<customerId>")
def get(self,request,customerId):
return DB.getCustomer(customerId)
@route("/",Http.POST)
def post(self,request,customerId,firstName,lastName):
customer = Customer(customerId, firstName, lastName)
DB.saveCustomer(customer)
return Response(201)
@route("/<customerId>",Http.PUT)
def put(self,request,customerId,firstName,lastName):
c = DB.getCustomer(customerId)
(c.firstName,c.lastName) = (firstName,lastName)
return Response(200)
@route("/<customerId>",Http.DELETE)
def delete(self,request,customerId):
DB.deleteCustomer(customerId)
return Response(200)
@route("/",Http.DELETE)
def deleteAll(self,request):
DB.deleteAllCustomers()
return Response(200)
class CustomerAddressRESTService():
path = "/customer/<customerId>/address"
@route("/")
def getAll(self,request,customerId):
return DB.getCustomer(customerId).addresses
@route("/<addressId>")
def get(self,request,customerId,addressId):
return DB.getCustomerAddress(customerId, addressId)
@route("/",Http.POST)
def post(self,request,customerId,addressId,streetNumber,streetName,stateCode,countryCode):
c = DB.getCustomer(customerId)
address = CustomerAddress(streetNumber,streetName,stateCode,countryCode)
c.addresses[addressId] = address
return Response(201)
@route("/<addressId>",Http.PUT)
def put(self,request,customerId,addressId,streetNumber,streetName,stateCode,countryCode):
address = DB.getCustomerAddress(customerId, addressId)
(address.streetNumber,address.streetName,address.stateCode,address.countryCode) = (streetNumber,streetName,stateCode,countryCode)
return Response(200)
@route("/<addressId>",Http.DELETE)
def delete(self,request,customerId,addressId):
DB.getCustomerAddress(customerId, addressId) #validate address exists
del(DB.getCustomer(customerId).addresses[addressId])
return Response(200)
@route("/",Http.DELETE)
def deleteAll(self,request,customerId):
c = DB.getCustomer(customerId)
c.addresses = {}
return Response(200)
def run_rest_app():
app = RESTResource((CustomerRESTService(),CustomerAddressRESTService()))
app.run(8080)
if __name__ == "__main__":
run_rest_app()
And the BDD showing off its different features
https://github.com/jacek99/corepost/blob/master/corepost/test/feature/rest_app.feature
Links
Changelog
- 0.0.16:
- minor bug fix for issue #4 (serializing object graphs to XML), removed Jinja2 as dependency:
- 0.0.15:
minor bug fixes in auto-converting responses to JSON and parsing arguments/paths with unexpectec characters
- 0.0.14:
automatic parsing of query, form, JSON, YAML and XML arguments: http://jacek99.github.com/corepost/argument_parsing.html
- 0.0.13:
perf fix to avoid unnecessary string concatenation when doing URL routing, after code review (thanks to Gerald Tremblay)
- 0.0.12:
backwards incompatible change: added advanced URL routing for nested REST services. CorePost object is gone, REST services are now just standard classes. They get wrapped in a RESTResource object (see sample above) when exposed
- 0.0.11:
added support for request/response filters
- 0.0.10:
removed dependency on txZMQ which was not needed at this point (yet)
- 0.0.9:
- fix for issue #3 (wrong class passes as ‘self’ to router method):
- 0.0.8:
support for serializing of classes to JSON,XML,YAML based on caller’s Accept header
separate routing functionality from CorePost Resource object, in preparation for future multicore support
- 0.0.7:
automatic parsing of incoming content (JSON, YAML, XML)
routing by incoming content type
automatic response conversion based on caller’s Accept header (JSON/YAML
support for defer.returnValue() in @inlineCallbacks route methods
0.0.6 - redesigned API around classes and methods, rather than functions and global objects (after feedback from Twisted devs)
0.0.5 - added FormEncode validation for arguments
0.0.4 - path argument extraction, mandatory argument error checking
Metadata
Release files for CorePost 0.0.16
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| CorePost-0.0.16.tar.gz | 11.9 kB | Without provenance | Details for CorePost-0.0.16.tar.gz |
Release files / CorePost-0.0.16.tar.gz
| Download URL | CorePost-0.0.16.tar.gz |
|---|---|
| Size | 11.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bec43025ad28b3b821af899dd62c721312f35848bd116a21d386db3d5bfec139
|
|
BLAKE2b-256 checksum How to use checksums |
72d3e9bee9ad89471a91692587d51d493d8e6f768c29077436cc6f1e67ec0038
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Security for CorePost 0.0.16
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.