Giter Site home page Giter Site logo

roku-requests's Introduction

roku-requests

Simple, python requests inspired Brightscript requests framework for Roku apps

build status monthly downloads npm version license Slack

Installation

Using ropm

ropm install roku-requests

Manually

Copy src/source/Requests.brs into your project as source/Requests.brs folder

Usage

Make a Request

Making a request with Requests is very simple.

Brightscript Debugger> r = Requests().get("https://api.github.com/events")

Now, we have a Response object called r. We can get all the information we need from this object.

Brightscript Debugger> ?r.ok
Brightscript Debugger> true
Brightscript Debugger> ?r.statuscode
Brightscript Debugger>  200

Requests’ simple API means that all forms of HTTP request are as obvious. For example, this is how you make an HTTP POST request:

Brightscript Debugger> r = Requests().post("https://httpbin.org/post", {"data":"value"})

What about the other HTTP request types: PUT, DELETE, HEAD and OPTIONS? These are all supported and simple by using the .request(VERB... method:

Brightscript Debugger> r = Requests().request("PUT", "https://httpbin.org/put", {"key":"value"})
Brightscript Debugger> r = Requests().request("DELETE", "https://httpbin.org/delete", {})
Brightscript Debugger> r = Requests().request("HEAD", "https://httpbin.org/get", {})
Brightscript Debugger> r = Requests().request("OPTIONS", "https://httpbin.org/get", {})

Passing Parameters In URLs

Brightscript Debugger> payload = {"key1": "value1", "key2": "value2"}
Brightscript Debugger> r = Requests().get("https://httpbin.org/get", {"params":payload})

You can see that the URL has been correctly encoded by printing the URL:

Brightscript Debugger> ?r.url
Brightscript Debugger> https://httpbin.org/get?key1=value1&key2=value2

Response Content

We can read the content of the server’s response. Consider the GitHub timeline again:

Brightscript Debugger> r = Requests().get("https://api.github.com/events")`
Brightscript Debugger> ?r.text
Brightscript Debugger> [{"id":"8575373301","type":"WatchEvent","actor":{"id":4537355,"login":"...

JSON Response Content

There’s also a builtin JSON encoder/decoder, in case you’re dealing with JSON data:

Brightscript Debugger> r = Requests().get("https://api.github.com/events")
Brightscript Debugger> ?r.json
Brightscript Debugger> <Component: roArray> =
[
    <Component: roAssociativeArray>
    <Component: roAssociativeArray>
    ...
]

You also also pass flags for json parsing. parseJsonFlags is passed to the ParseJson() function.

Brightscript Debugger> r = Requests().get("https://api.github.com/events", {parseJsonFlags:"i"})
Brightscript Debugger> ?r.json

Or disable json parsing

Brightscript Debugger> r = Requests().get("https://api.github.com/events", {parseJson:false})
Brightscript Debugger> ?r.json

Custom Headers

If you’d like to add HTTP headers to a request, simply pass in an AA to the headers key in the args dictionary.

Brightscript Debugger> url =
Brightscript Debugger> headers = {"user-agent": "my-app/0.0.1"}
Brightscript Debugger> r = Requests().get(url, {"headers":headers})

More complicated POST requests

Instead of encoding the AA yourself, you can also pass it directly using the json parameter

Brightscript Debugger> url = "https://httpbin.org/post"
Brightscript Debugger> payload = {"some": "data"}
Brightscript Debugger> r = Requests().post(url, {"json":payload})

Using the json parameter in the request will change the Content-Type in the header to application/json.

Response Status Codes

Brightscript Debugger> r = Requests().get("https://httpbin.org/get")
Brightscript Debugger> ?r.statuscode
Brightscript Debugger>  200

Response Headers

We can view the server’s response headers using an AA:

Brightscript Debugger> ?r.headers
Brightscript Debugger> <Component: roAssociativeArray> =
{
    access-control-allow-credentials: "true"
    access-control-allow-origin: "*"
    connection: "keep-alive"
    content-length: "272"
    content-type: "application/json"
    date: "Mon, 12 Nov 2018 17:25:53 GMT"
    server: "gunicorn/19.9.0"
    via: "1.1 vegur"
}

Timeouts

You can tell Requests to stop waiting for a response after a given number of seconds with the timeout parameter (int).

Brightscript Debugger> r = Requests().get("https://httpbin.org/delay/10", {"timeout":1})
Brightscript Debugger> <Component: roAssociativeArray> =
{
    cachehit: false
    ok: false
    timestried: 1
    url: "https://httpbin.org/delay/10"
}

Caching

You can tell Requests to use cache (on by default) by passing the useCache parameter (boolean). This will automatically cache the request if there are cache-control headers in the response.

Brightscript Debugger> r = Requests().get("https://httpbin.org/cache/60", {"useCache":true})

You can see if the cache was hit by checking the cacheHit value on the Response object.

Brightscript Debugger> r = Requests().get("https://httpbin.org/cache/60", {"useCache":true})
Brightscript Debugger> ?r.cachehit
Brightscript Debugger> false
Brightscript Debugger> r = Requests().get("https://httpbin.org/cache/60", {"useCache":true})
Brightscript Debugger> ?r.cachehit
Brightscript Debugger> true

If the server does not return cache-control headers or you want to manually specify the time to cache a request just pass the cacheSeconds parameter (int) to Requests.

Brightscript Debugger> r = Requests().get("https://httpbin.org/get", {"useCache":true, "cacheSeconds":300})

Notes about Cache implementation

Roku's Cachefs:

  • The cache implementation uses Roku's cachefs (https://sdkdocs.roku.com/display/sdkdoc/File+System)
  • cachefs is available as a Beta feature starting in Roku OS 8.
  • cachefs exists across channel launches but will evict data when more space is required for another Channel.

Cache Keys and Storage Location

  • Requests uses an MD5 hash of the URL + Request Headers being passed as the cache key
  • Requests stores the cached request as a file in cachefs:/{MD5_HASH}. Please be aware of this if your channel is storing things in the cachefs:/ space as there is a very minute possiibility of name collisions.
  • The cache data is stored as a file with the first line as a unix epoch of the time the file was written (time the first request was made). Subsequient requests read the file and compute/compare timestamps to determine if the cached file is still valid or not.

Development

Roku Requests is an independent open-source project, maintained exclusively by volunteers.

You might want to help! Get in touch via the slack group, or raise issues.

roku-requests's People

Contributors

bvisin avatar cewert avatar dependabot[bot] avatar ibicha avatar twitchbronbron avatar zeed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

roku-requests's Issues

Fix test project

The test project currently uses rooibos, and has a few syntax errors. @georgejecook can you give this a quick look and get the tests working again?

Add option not to parse response as JSON

It would be great if parsing responses as JSON could be made optional. I am accessing an API that accepts JSON in request body but responds only with the string "ok". This results in errors such as ERROR: ParseJSON: Unknown identifier 'ok'.

Could there be an option for it? Alternatively, the parsing could be dependent on the response content-type.

Array in POST body

Please add support for array in POST request
Request.brs, line 54
if args.json <> invalid and (type(args.json) = "roAssociativeArray" or type(args.json) = "roArray")

Better handling of XML response

Request shouldn't try parsing obvious HTML/XML, e.g. anything starting with a < for instance, possibly also response starting with whitespace.

Some design considerations

I recently started using this library, and it's going great, loving lots of the built-in features!

But I'm also hitting some of the limitations that other libs of this kind don't face:

  • The ability to "build" the request, but not send it yet
  • Send the request in parallel with other requests

In short, sending a request today is doing everything in one shot: build a request, send, wait for a response.

This needs to potentially become 3 methods:

  • Request() (get()/post()/etc)
  • Send()
  • Await()

This way, it becomes possible to send multiple requests, and control the flow of blocking the UI until a request is ready. (And by blocking the UI I don't mean blocking the UI thread, I know this lib does async behind the scenes)

crash if param value is invalid

                m._qs_array.push([param, key])```

crashses if one of the params is invalid. If I get time I'll submit a pr - flagging so there's somewhere to track this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.