Giter Site home page Giter Site logo

valpackett / magicbane Goto Github PK

View Code? Open in Web Editor NEW
119.0 8.0 8.0 0 B

A web framework that integrates Servant, EKG, fast-logger, wai-cli… | now on https://codeberg.org/valpackett/magicbane

Home Page: https://codeberg.org/valpackett/magicbane

License: The Unlicense

servant haskell web web-framework

magicbane's Introduction

magicbane's People

Contributors

valpackett avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

magicbane's Issues

magicbane-0.4.1 not found on Hackage

A recent PR fixed an issue with LTS 14.1. As part of the change-set for that fix this library's version was bumped to version 0.4.1. However, when I ask stack to include magicbane-0.4.1 it cannot be found on Hackage.

2019-09-10 12:53:49.510243: [error] Could not find magicbane-0.4.1 on Hackage
Possible candidates: magicbane-0.4.0@sha256:d47fc4467985283aa20dc538e14e05cccb06fa048c92f42afa391cfa19beee8b,2170.

Could you please check that magicbane-0.4.1 has been correctly published. It's entirely possible I'm not using the stack tool correctly. Thanks.

Conflicting exports for 'host' when building against latest wai-cli

I'm trying to build my project which references magicbane-0.4.0, but with extra-deps:

extra-deps:
- github: myfreeweb/wai-cli
  commit: 6cdd4d03a538a16b7f94ea9fca79bdab0d103d35

in order to compile against latest wai-cli.

The stack build of magicbane is failing with:

    /tmp/stack4749/magicbane-0.4.0/library/Magicbane.hs:13:3: error:
        Conflicting exports for ‘host’:
           ‘module X’ exports ‘X.host’
             imported from ‘Network.Wai.Cli’ at library/Magicbane.hs:32:1-51
           ‘module X’ exports ‘X.host’
             imported from ‘Magicbane.HTTPClient’ at library/Magicbane.hs:39:1-42
             (and originally defined in ‘http-client-0.5.14:Network.HTTP.Client.Types’)

Does it just need a hiding(host) in https://github.com/myfreeweb/magicbane/blob/master/library/Magicbane.hs#L32 ? Or am I trying to do something which isn't expected to work?

(the reason I'm trying to do this is I'm looking to put together a pull request for wai-cli to allow building on windows)

fails to build with either-5

For Stackage Nightly:

Building library for magicbane-0.1.3..
[1 of 8] Compiling Magicbane.App    ( library/Magicbane/App.hs, dist/build/Magicbane/App.o )
[2 of 8] Compiling Magicbane.Logging ( library/Magicbane/Logging.hs, dist/build/Magicbane/Logging.o )
[3 of 8] Compiling Magicbane.Metrics ( library/Magicbane/Metrics.hs, dist/build/Magicbane/Metrics.o )
[4 of 8] Compiling Magicbane.Util   ( library/Magicbane/Util.hs, dist/build/Magicbane/Util.o )
[5 of 8] Compiling Magicbane.HTTPClient ( library/Magicbane/HTTPClient.hs, dist/build/Magicbane/HTTPClient.o )

library/Magicbane/HTTPClient.hs:13:1: error:
    Could not find module ‘Control.Monad.Trans.Either’
    Perhaps you meant
      Control.Monad.Trans.Writer (from transformers-0.5.2.0)
      Control.Monad.Trans.Error (from transformers-0.5.2.0)
      Control.Monad.Trans.Reader (from transformers-0.5.2.0)
    Use -v to see a list of the files searched for.
   |
13 | import           Control.Monad.Trans.Either

Example "larger.hs" doesn't compile in stack lts-12.21

I haven't investigated this a lot yet, but in my app, it looks like trying to use the env var-driven config is a recipe for build errors. I'm following along with the larger.hs example. Removing the typeclass instance for DefConfig results in a missing instance, having DefConfig but no FromEnv is fine (until you want to parse config from env vars), and having DefConfig/FromEnv without a definition for fromEnv doesn't change the behavior.

I have not tried multiple LTS resolvers yet. If there's a particular resolver I should use, I'm open to suggestions. I also have not double-checked the official library's documentation. Even if there's relevant info in upstream documentation, we should work on making sure the examples compile for reasonably recent stack setups.

Here's a sample of what happens when compiling the example larger.hs straight from this repository in my project (As close as I can easily get to a minimal, complete, verifiable example):

user@host ~/project $ stack ghc larger.hs 
[1 of 1] Compiling Main             ( larger.hs, larger.o )

larger.hs:18:13: error:
    • Overlapping instances for DefConfig LargeAppConf
        arising from a use of ‘gFromEnvCustom’
      Matching instances:
        instance Default α => DefConfig α -- Defined in ‘Magicbane’
        instance DefConfig LargeAppConf -- Defined at larger.hs:12:10
    • In the expression:
        gFromEnvCustom
          Option {dropPrefixCount = 0, customPrefix = "LARGEAPP"}
      In an equation for ‘fromEnv’:
          fromEnv
            = gFromEnvCustom
                Option {dropPrefixCount = 0, customPrefix = "LARGEAPP"}
      In the instance declaration for ‘FromEnv LargeAppConf’
   |
18 |   fromEnv = gFromEnvCustom Option { dropPrefixCount = 0, customPrefix = "LARGEAPP" }
   |

I'm familiar with basic Haskell, and very new to Magicbane (and all of its dependencies), but let me know if there's anything else I can do to help with this.

Overlapping instances for HasLogFunc SimpleApp

In my init code, I wanted to use RIO's runSimpleApp for some code that needs a logging environment, before I've built my application context - creating a sql connection pool wants a MonadLogger instance - and RIO doesn't export any function to write to console without a logger. But, I can't do that because there is an overlapping instance:

    • Overlapping instances for HasLogFunc SimpleApp
        arising from a use of ‘createPostgresqlPool’
      Matching instances:
        instance Has ModLogger α => HasLogFunc α
          -- Defined in ‘Magicbane.Logging’
        instance HasLogFunc SimpleApp -- Defined in ‘RIO.Prelude.Simple’

Consider replacing ClassyPrelude with RIO (revisited)

In the wake of #10, we now have:

Okay, what's MagicbaneApp?

newtype MagicbaneApp β α = MagicbaneApp {
 unMagicbaneApp ∷ ReaderT β IO α }

It's just a ReaderT over IO!

This is exactly the RIO monad:

newtype RIO env a = RIO { unRIO :: ReaderT env IO a }

It would be nice to unify these!

Suggest changing license from UNLICENSE/public domain to BSD3

This is just a friendly suggestion meant to help you achieve your own goals.

Some pointers to this end:

Particularly,

Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

Poor type interaction with :<|>

Given:

type EntitiesAPI = "entities"
  :> Capture "objtype" Object
  :> Capture "uuid" IdDynamic
  :> EntityAPI

type EntityAPI
  =    Get '[JSON] APIResult
  :<|> Capture "childtype" Text
       :> Get '[JSON] APIResult

entitiesHandler obj uuid = getEntityAPI bare :<|> const (getEntityAPI full)
  where
    bare = EntityAPIRequest obj uuid False
    full = EntityAPIRequest obj uuid True

getEntityAPI x = _

With Servant, I have the following types:

entitiesHandler :: Server EntitiesAPI
getEntityAPI :: EntityAPIRequest -> Handler APIResult

With Magicbane, they become:

entitiesHandler :: Object -> IdDynamic -> MyApp APIResult :<|> (Text -> MyApp APIResult)
getEntityAPI :: EntityAPIRequest -> MyApp APIResult

The latter may not be a problem (I haven't directly hit an issue with it, but the change seems notable). The former, however, has some nasty implications. This will eventually be only one part of the API. I also have:

type MyAPI
  =    EntitiesAPI
  -- more here later

api
  =    entitiesHandler
  -- More here later

The comparative types of api are:

api :: Server MyAPI
-- vs. --
api :: Object -> IdDynamic -> MyApp APIResult :<|> (Text -> MyApp APIResult)

That looks like it's going to become a nightmare as I fill out the API. I noticed that the examples mostly just don't have type annotations, but I'm working in a team environment and they're not something I want to give up. Is there a path forward from here?

Consider dropping Data.Has

I keep running into issues arising from Has, and especially its interplay with the concrete HasFoo class idiom. Today this culminated in encountering a runtime loop on code that shouldn't even typecheck (trivial reproduction here). This has thoroughly convinced me that @snoyberg chose the more stable path with RIO, and I've now fallen back to exclusively using HasFoo (with the exception of one instance Has ModHttpClient AppEnv since that's required to use the API).

Name conflict with RIO on fromString

RIO exports Data.String.fromString (IsString typeclass member). Magicbane currently exports Data.String.Conversions.Monomorphic.fromString, a type-constrained alias for Data.String.Conversions.cs. As all of the types supported by the latter have IsString instances, I don't believe there is any benefit in providing the non-base version.

I have a PR ready to address this but today's GitHub issues are currently preventing me from pushing it.

magicbane-0.2.0 build failure with http-conduit-2.3

As seen on the Stackage build server:

magicbane: BuildFailureException Process exited with ExitFailure 1: ./Setup build

[6 of 9] Compiling Magicbane.HTTPClient ( library/Magicbane/HTTPClient.hs, dist/
build/Magicbane/HTTPClient.o )

library/Magicbane/HTTPClient.hs:69:25: error:
    • Could not deduce (unliftio-core-0.1.1.0:Control.Monad.IO.Unlift.MonadUnlif
tIO
                          μ)
        arising from a use of ‘HCC.withResponse’
      from the context: (MonadHTTP ψ μ, MonadCatch μ)
        bound by the type signature for:
                   performWithFn :: forall ψ (μ :: * -> *) ι ρ.
                                    (MonadHTTP ψ μ, MonadCatch μ) =>
                                    (ConduitM ι ByteString μ () -> μ ρ)
                                    -> Request -> ExceptT Text μ (Response ρ)
        at library/Magicbane/HTTPClient.hs:67:1-122
      Possible fix:
        add (unliftio-core-0.1.1.0:Control.Monad.IO.Unlift.MonadUnliftIO
               μ) to the context of
          the type signature for:
            performWithFn :: forall ψ (μ :: * -> *) ι ρ.
                             (MonadHTTP ψ μ, MonadCatch μ) =>
                             (ConduitM ι ByteString μ () -> μ ρ)
                             -> Request -> ExceptT Text μ (Response ρ)
    • In the expression: HCC.withResponse req
      In the second argument of ‘($)’, namely
        ‘HCC.withResponse req
           $ \ res
               -> do body <- fn $ responseBody res
                     return res {responseBody = body}’
      In the second argument of ‘($)’, namely
        ‘tryAny
           $ HCC.withResponse req
               $ \ res
                   -> do body <- fn $ responseBody res
                         return res {responseBody = body}’
   |
69 |   res ← lift $ tryAny $ HCC.withResponse req $ \res → do
   |                         ^^^^^^^^^^^^^^^^^^^^

I was able to reproduce locally like so:

stack unpack magicbane-0.2.0 && cd magicbane-0.2.0
edit stack.yaml # add the following stack.yaml
stack build
# stack.yaml
resolver: nightly-2018-03-10
extra-deps:
- servant-0.13
- servant-server-0.13
- http-types-0.12.1
- http-conduit-2.3.0

(discussion) Keeping an eye on RIO?

Magicbane asserts Snoyman's classy-prelude. With the recent reveal of RIO, and Snoyman on board that project, it may be worth considering the benefits/logistics of moving to it.

Exception Handling

In my application, I would like for the Wai Logger middleware to write a message to the log when an unhandled exception occurs and 500 response is sent to the client. For this to happen, it looks we need to catch that exception and respond inside our Application. A basic example of how this would be done in servant is

app :: Application
app = serve api $ hoistServer api nt server

nt :: Handler a -> Handler a
nt = handleAny throwEx
    where
      throwEx e = throwError $ err500 {errBody = "The following server exception occured: " <> (cs $ show e)}

How can I do the same thing using magicbaneApp ? Or is this something magicbane could do?

Examples won't build in stackage LTS-9.0

Hi,

Trying to build the examples in stackage LTS-9.0 gives this error (for tiny.hs, but I've also seen this with larger.hs and an app I was working on):

> stack build
magicbane-examples-0.0.0: build (exe)
Preprocessing executable 'tiny' for magicbane-examples-0.0.0...
[1 of 1] Compiling Main             ( tiny.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/tiny/tiny-tmp/Main.o )

/Users/ericrochester/tmp/magicbane/examples/tiny.hs:17:16: error:
    • Couldn't match type ‘Handler’ with ‘ExceptT ServantErr IO’
        arising from a functional dependency between:
          constraint ‘servant-0.11:Servant.Utils.Enter.Enter
                        (BasicApp Text)
                        (MagicbaneApp BasicContext)
                        (ExceptT ServantErr IO)
                        (Handler Text)’
            arising from a use of ‘magicbaneApp’
          instance ‘servant-0.11:Servant.Utils.Enter.Enter (m a) m n (n a)’
            at <no location info>
    • In the second argument of ‘($)’, namely
        ‘magicbaneApp exampleAPI EmptyContext ctx hello’
      In a stmt of a 'do' block:
        defWaiMain $ magicbaneApp exampleAPI EmptyContext ctx hello
      In the expression:
        do { ctx <- newBasicContext;
             defWaiMain $ magicbaneApp exampleAPI EmptyContext ctx hello }

--  While building package magicbane-examples-0.0.0 using:
      /Users/ericrochester/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.24.2.0 build exe:tiny --ghc-options " -ddump-hi -ddump-to-file"
    Process exited with code: ExitFailure 1

For reference, package.yaml looks like:

name: magicbane-examples
dependencies:
  - base >=4.8.0.0 && <5
  - magicbane
executables:
  tiny:
    main: tiny.hs
    source-dirs: .
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N

Should I be using magicbane from master branch instead of the release?

Thanks,
Eric

"instance HasModLogger a => HasLogFunc a" overlaps on bare LogFunc

    • Overlapping instances for HasLogFunc ModLogger
        arising from a use of ‘logFuncL’
      Matching instances:
        instance Has ModLogger α => HasLogFunc α
          -- Defined at /home/tejon/magicbane/library/Magicbane/Logging.hs:17:10
        instance HasLogFunc LogFunc
          -- Defined in ‘rio-0.1.3.0:RIO.Prelude.Logger’

I tried fixing this via Data.Type.Equality:

instance ((α == ModLogger) ~ 'False, Has ModLogger α) ⇒ HasLogFunc α where
  logFuncL = hasLens

But this doesn't work for reasons I haven't yet grasped. There's a procedural workaround described on Stack Overflow by @treeowl; I didn't immediately grok how to adapt it, and in any case it involves an additional class and newtype so I'd want your feedback on module style (per #12) before doing something like that.

Unable to use with Servant Server 0.18.1

Hi, I'm new to Haskell and Magicbane seems like a really nice collection of things, especially to simplify adding some essentials to Servant - so thanks very much for the library!

However, I'm trying to use Magicbane with the latest Servant Server (0.18.1) and I'm getting the following compilation error:

servant-server                    > Registering library for servant-server-0.18.1..
magicbane                         > configure
magicbane                         > Configuring magicbane-0.4.1...
magicbane                         > build
magicbane                         > Preprocessing library for magicbane-0.4.1..
magicbane                         > Building library for magicbane-0.4.1..
magicbane                         > [ 1 of 10] Compiling Magicbane.App
magicbane                         > 
magicbane                         > /tmp/stack-c4a82860c00c798d/magicbane-0.4.1/library/Magicbane/App.hs:22:37: error:
magicbane                         >     • Could not deduce (HasContextEntry
magicbane                         >                           (ψ .++ DefaultErrorFormatters) ErrorFormatters)
magicbane                         >         arising from a use of ‘serveWithContext’
magicbane                         >       from the context: HasServer χ ψ
magicbane                         >         bound by the type signature for:
magicbane                         >                    magicbaneApp :: forall β χ (ψ :: [*]).
magicbane                         >                                    HasServer χ ψ =>
magicbane                         >                                    Proxy χ -> Context ψ -> β -> ServerT χ (RIO β) -> Application
magicbane                         >         at library/Magicbane/App.hs:21:1-104
magicbane                         >     • In the expression: serveWithContext api sctx
magicbane                         >       In the expression: serveWithContext api sctx $ srv ctx
magicbane                         >       In an equation for ‘magicbaneApp’:
magicbane                         >           magicbaneApp api sctx ctx actions
magicbane                         >             = serveWithContext api sctx $ srv ctx
magicbane                         >             where
magicbane                         >                 srv c
magicbane                         >                   = hoistServerWithContext
magicbane                         >                       api (Proxy @ψ) (runMagicbaneHandler c) actions
magicbane                         >    |
magicbane                         > 22 | magicbaneApp api sctx ctx actions = serveWithContext api sctx $ srv ctx
magicbane                         >    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^
magicbane                         > 

My reason for using a more recent version of Servant is so that I can implement custom parse errors for request inputs, as in https://docs.servant.dev/en/stable/cookbook/custom-errors/CustomErrors.html.

I realize I can probably just implement a custom FromJSON, but I was hoping for a neater solution, using Servant ErrorFormatters with Magicbane.

Can someone please suggest a workaround for this?

{instance (Default α) ⇒ DefConfig α} breaks things

• Overlapping instances for DefConfig SystemEnv
        arising from a use of ‘gFromEnvCustom’
      Matching instances:
        instance data-default-class-0.1.2.0:Data.Default.Class.Default α =>
                 DefConfig α
          -- Defined in ‘Magicbane’
        instance DefConfig {redacted}
          -- Defined at {redacted}
    • In the expression:
        gFromEnvCustom Option {dropPrefixCount = 1, customPrefix = ""}
      In an equation for ‘fromEnv’:
          fromEnv
            = gFromEnvCustom Option {dropPrefixCount = 1, customPrefix = ""}
      In the instance declaration for ‘FromEnv {redacted}’

This happens if Magicbane is imported anywhere in the module's upstream dependency tree, even hiding everything; hooray for global instances. It's particularly disturbing that I have no idea where a Default instance could have possibly come from for the type I'm trying to parse into.

In this case I'm able to work around it by only importing Magicbane.App and Magicbane.HTTPClient upstream. However, Default is a widely-reviled antipattern and by preference I'd have it gone even if it didn't make things explode. On the other hand, killing it could cause significant downstream breakage.

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.