Safe Haskell | None |
---|---|
Language | Haskell2010 |
- type PythonGenerator = [PythonRequest] -> Text
- data ReturnStyle
- data PythonRequest
- data PyRequestArgs = PyRequestArgs {}
- data CommonGeneratorOptions = CommonGeneratorOptions {
- functionNameBuilder :: FunctionName -> Text
- requestBody :: Text
- urlPrefix :: Text
- indentation :: Proxy Indent -> Text
- returnMode :: ReturnStyle
- defCommonGeneratorOptions :: CommonGeneratorOptions
- defaultPyIndent :: Proxy Indent -> Text
- indent :: Proxy Indent
- type Indent = (" " :: Symbol)
- indenter :: Int -> Proxy Indent -> Text
- makePyUrl :: CommonGeneratorOptions -> PythonRequest -> Text -> Text
- makePyUrl' :: forall f. CommonGeneratorOptions -> Req f -> Text -> Text
- segmentToStr :: Segment f -> Text
- capturesToFormatArgs :: [Segment f] -> [Text]
- toValidFunctionName :: Text -> Text
- functionName :: CommonGeneratorOptions -> PythonRequest -> Text
- toPyHeader :: HeaderArg f -> Text
- retrieveHeaders :: PythonRequest -> [Text]
- getHeaderDict :: PythonRequest -> Text
- retrieveHeaderText :: forall f. HeaderArg f -> Text
- toPyDict :: Text -> [Text] -> Text
- toPyParams :: Text -> [QueryArg f] -> Text
- getParams :: Text -> PythonRequest -> Text
- paramNames :: PythonRequest -> [Text]
- captures :: PythonRequest -> [Text]
- getMethod :: PythonRequest -> Text
- hasBody :: PythonRequest -> Bool
- withFormattedCaptures :: Text -> [Segment f] -> Text
- buildDocString :: PythonRequest -> CommonGeneratorOptions -> Text -> Text
- buildHeaderDict :: [HeaderArg f] -> Text
- functionArguments :: forall f. Req f -> Text
- formatBuilder :: Text -> Text
- remainingReqCall :: PyRequestArgs -> Int -> Text
- data a :<|> b :: * -> * -> * = a :<|> b
- data (k :> k1) path a :: forall k k1. k1 -> k -> *
- defReq :: Req ftype
- reqHeaders :: Functor f => ([HeaderArg f0] -> f [HeaderArg f0]) -> Req f0 -> f (Req f0)
- class HasForeign k lang ftype api where
- class HasForeignType k k1 lang ftype a where
- class GenerateList ftype reqs where
- data NoTypes :: *
- data ArgType :: *
- data HeaderArg f :: * -> *
- = HeaderArg {
- _headerArg :: Arg f
- | ReplaceHeaderArg {
- _headerArg :: Arg f
- _headerPattern :: Text
- = HeaderArg {
- data QueryArg f :: * -> * = QueryArg {
- _queryArgName :: Arg f
- _queryArgType :: ArgType
- data Req f :: * -> * = Req {
- _reqUrl :: Url f
- _reqMethod :: Method
- _reqHeaders :: [HeaderArg f]
- _reqBody :: Maybe f
- _reqReturnType :: Maybe f
- _reqFuncName :: FunctionName
- newtype Segment f :: * -> * = Segment {
- unSegment :: SegmentType f
- data SegmentType f :: * -> *
- = Static PathSegment
- | Cap (Arg f)
- data Url f :: * -> * = Url {}
- type Path f = [Segment f]
- data Arg f :: * -> * = Arg {
- _argName :: PathSegment
- _argType :: f
- newtype FunctionName :: * = FunctionName {
- unFunctionName :: [Text]
- newtype PathSegment :: * = PathSegment {}
- concatCase :: FunctionName -> Text
- snakeCase :: FunctionName -> Text
- camelCase :: FunctionName -> Text
- data ReqBody k contentTypes a :: forall k. [*] -> k -> *
- data JSON :: *
- data FormUrlEncoded :: *
- type Post k = Verb k StdMethod POST 200
- type Get k = Verb k StdMethod GET 200
- data Raw :: *
- data Header sym a :: Symbol -> * -> *
Documentation
type PythonGenerator = [PythonRequest] -> Text Source #
data PythonRequest Source #
data CommonGeneratorOptions Source #
This structure is used by specific implementations to let you customize the output
CommonGeneratorOptions | |
|
defCommonGeneratorOptions :: CommonGeneratorOptions Source #
Default options.
> defCommonGeneratorOptions = CommonGeneratorOptions > { functionNameBuilder = snakeCase > , requestBody = "body" > , urlPrefix = "" > , indentation = " " -- 4 spaces > , returnMode = DangerMode > }
makePyUrl :: CommonGeneratorOptions -> PythonRequest -> Text -> Text Source #
makePyUrl' :: forall f. CommonGeneratorOptions -> Req f -> Text -> Text Source #
segmentToStr :: Segment f -> Text Source #
capturesToFormatArgs :: [Segment f] -> [Text] Source #
toValidFunctionName :: Text -> Text Source #
Attempts to reduce the function name provided to that allowed by
.Foreign
For valid Python function identifiers see the following: https://docs.python.org/3.2/reference/lexical_analysis.html#identifiers valid start chars: Lu, Ll, Lt, Lm, Lo, Nl, the underscore valid continuation chars: valid start chars <> Mn, Mc, Nd, Pc
toPyHeader :: HeaderArg f -> Text Source #
retrieveHeaders :: PythonRequest -> [Text] Source #
getHeaderDict :: PythonRequest -> Text Source #
retrieveHeaderText :: forall f. HeaderArg f -> Text Source #
paramNames :: PythonRequest -> [Text] Source #
captures :: PythonRequest -> [Text] Source #
getMethod :: PythonRequest -> Text Source #
hasBody :: PythonRequest -> Bool Source #
buildDocString :: PythonRequest -> CommonGeneratorOptions -> Text -> Text Source #
buildHeaderDict :: [HeaderArg f] -> Text Source #
functionArguments :: forall f. Req f -> Text Source #
formatBuilder :: Text -> Text Source #
remainingReqCall :: PyRequestArgs -> Int -> Text Source #
data a :<|> b :: * -> * -> * infixr 8 #
Union of two APIs, first takes precedence in case of overlap.
Example:
>>>
:{
type MyApi = "books" :> Get '[JSON] [Book] -- GET /books :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] () -- POST /books :}
a :<|> b infixr 8 |
(HasForeign k lang ftype a, HasForeign k lang ftype b) => HasForeign k lang ftype ((:<|>) a b) | |
(GenerateList ftype start, GenerateList ftype rest) => GenerateList ftype ((:<|>) start rest) | |
Functor ((:<|>) a) | |
Foldable ((:<|>) a) | |
Traversable ((:<|>) a) | |
(Bounded b, Bounded a) => Bounded ((:<|>) a b) | |
(Eq b, Eq a) => Eq ((:<|>) a b) | |
(Show b, Show a) => Show ((:<|>) a b) | |
(Semigroup a, Semigroup b) => Semigroup ((:<|>) a b) | |
(Monoid a, Monoid b) => Monoid ((:<|>) a b) | |
type Foreign ftype ((:<|>) a b) | |
data (k :> k1) path a :: forall k k1. k1 -> k -> * infixr 9 #
The contained API (second argument) can be found under ("/" ++ path)
(path being the first argument).
Example:
>>>
-- GET /hello/world
>>>
-- returning a JSON encoded World value
>>>
type MyApi = "hello" :> "world" :> Get '[JSON] World
(KnownSymbol sym, HasForeignType * k lang ftype [t], HasForeign k lang ftype sublayout) => HasForeign k lang ftype ((:>) * * (CaptureAll * sym t) sublayout) | |
(KnownSymbol sym, HasForeignType * k lang ftype a, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (Header sym a) api) | |
(KnownSymbol sym, HasForeignType k k1 lang ftype a, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (QueryParam k sym a) api) | |
(KnownSymbol sym, HasForeignType * k lang ftype [a], HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (QueryParams * sym a) api) | |
(KnownSymbol sym, HasForeignType * k lang ftype Bool, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (QueryFlag sym) api) | |
(Elem * JSON list, HasForeignType k k1 lang ftype a, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (ReqBody k list a) api) | |
(KnownSymbol path, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * Symbol path api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * RemoteHost api) | |
(KnownSymbol sym, HasForeignType k k1 lang ftype t, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (Capture k sym t) api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * IsSecure api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * Vault api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * HttpVersion api) | |
type Foreign ftype ((:>) * * HttpVersion api) | |
type Foreign ftype ((:>) * * Vault api) | |
type Foreign ftype ((:>) * * IsSecure api) | |
type Foreign ftype ((:>) * * RemoteHost api) | |
type Foreign ftype ((:>) * Symbol path api) | |
type Foreign ftype ((:>) * * (ReqBody k list a) api) | |
type Foreign ftype ((:>) * * (QueryFlag sym) api) | |
type Foreign ftype ((:>) * * (QueryParams * sym a) api) | |
type Foreign ftype ((:>) * * (QueryParam k sym a) api) | |
type Foreign ftype ((:>) * * (Header sym a) api) | |
type Foreign ftype ((:>) * * (CaptureAll * sym t) sublayout) | |
type Foreign ftype ((:>) * * (Capture k sym a) api) | |
class HasForeign k lang ftype api where #
HasForeign k lang ftype Raw | |
(HasForeign k lang ftype a, HasForeign k lang ftype b) => HasForeign k lang ftype ((:<|>) a b) | |
HasForeign k lang ftype api => HasForeign k lang ftype (WithNamedContext name context api) | |
(KnownSymbol sym, HasForeignType * k lang ftype [t], HasForeign k lang ftype sublayout) => HasForeign k lang ftype ((:>) * * (CaptureAll * sym t) sublayout) | |
(KnownSymbol sym, HasForeignType * k lang ftype a, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (Header sym a) api) | |
(KnownSymbol sym, HasForeignType k k1 lang ftype a, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (QueryParam k sym a) api) | |
(KnownSymbol sym, HasForeignType * k lang ftype [a], HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (QueryParams * sym a) api) | |
(KnownSymbol sym, HasForeignType * k lang ftype Bool, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (QueryFlag sym) api) | |
(Elem * JSON list, HasForeignType k k1 lang ftype a, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (ReqBody k list a) api) | |
(KnownSymbol path, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * Symbol path api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * RemoteHost api) | |
(KnownSymbol sym, HasForeignType k k1 lang ftype t, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (Capture k sym t) api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * IsSecure api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * Vault api) | |
HasForeign k lang ftype api => HasForeign k lang ftype ((:>) * * HttpVersion api) | |
(Elem * JSON list, HasForeignType k k2 lang ftype a, ReflectMethod k1 method) => HasForeign k2 lang ftype (Verb k k1 method status list a) | |
class HasForeignType k k1 lang ftype a where #
HasForeignType
maps Haskell types with types in the target
language of your backend. For example, let's say you're
implementing a backend to some language X, and you want
a Text representation of each input/output type mentioned in the API:
-- First you need to create a dummy type to parametrize your -- instances. data LangX -- Otherwise you define instances for the types you need instance HasForeignType LangX Text Int where typeFor _ _ _ = "intX" -- Or for example in case of lists instance HasForeignType LangX Text a => HasForeignType LangX Text [a] where typeFor lang type _ = "listX of " <> typeFor lang ftype (Proxy :: Proxy a)
Finally to generate list of information about all the endpoints for an API you create a function of a form:
getEndpoints :: (HasForeign LangX Text api, GenerateList Text (Foreign Text api)) => Proxy api -> [Req Text] getEndpoints api = listFromAPI (Proxy :: Proxy LangX) (Proxy :: Proxy Text) api
-- If language __X__ is dynamically typed then you can use -- a predefined NoTypes parameter with the NoContent output type:
getEndpoints :: (HasForeign NoTypes NoContent api, GenerateList Text (Foreign NoContent api)) => Proxy api -> [Req NoContent] getEndpoints api = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) api
HasForeignType Symbol * Python Text a # | |
HasForeignType k * NoTypes NoContent ftype | |
HasForeignType * * Python Text Bool # | |
HasForeignType * * Python Text Int # | |
HasForeignType * * Python Text ByteString # | |
HasForeignType * * Python Text ByteString # | |
HasForeignType * * Python Text String # | |
HasForeignType * * Python Text Text # | |
HasForeignType * * Python Text JSON # | |
HasForeignType * * Python Text NoContent # | |
HasForeignType * * Python Text a => HasForeignType * * Python Text [a] # | |
HasForeignType Symbol * Python Text a => HasForeignType * * Python Text [Header a b] # | |
HasForeignType * * Python Text a => HasForeignType * * Python Text (Maybe a) # | |
HasForeignType Symbol * Python Text a => HasForeignType * * Python Text (Headers ((:) * (Header a b) ([] *)) c) # | |
HasForeignType [*] * Python Text a => HasForeignType (* -> *) * Python Text (Headers a) # | |
HasForeignType Symbol * Python Text a => HasForeignType (* -> *) * Python Text (Header a) # | |
class GenerateList ftype reqs where #
Utility class used by listFromAPI
which computes
the data needed to generate a function for each endpoint
and hands it all back in a list.
generateList :: reqs -> [Req ftype] #
GenerateList ftype (Req ftype) | |
(GenerateList ftype start, GenerateList ftype rest) => GenerateList ftype ((:<|>) start rest) | |
HeaderArg | |
| |
ReplaceHeaderArg | |
|
QueryArg | |
|
Req | |
|
Segment | |
|
data SegmentType f :: * -> * #
Static PathSegment | a static path segment. like "/foo" |
Cap (Arg f) | a capture. like "/:userid" |
Eq f => Eq (SegmentType f) | |
Show f => Show (SegmentType f) | |
Arg | |
|
newtype FunctionName :: * #
newtype PathSegment :: * #
concatCase :: FunctionName -> Text #
Function name builder that simply concat each part together
snakeCase :: FunctionName -> Text #
Function name builder using the snake_case convention. each part is separated by a single underscore character.
camelCase :: FunctionName -> Text #
Function name builder using the CamelCase convention. each part begins with an upper case character.
data ReqBody k contentTypes a :: forall k. [*] -> k -> * #
Extract the request body as a value of type a
.
Example:
>>>
-- POST /books
>>>
type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book
(Elem * JSON list, HasForeignType k k1 lang ftype a, HasForeign k1 lang ftype api) => HasForeign k1 lang ftype ((:>) * * (ReqBody k list a) api) | |
type Foreign ftype ((:>) * * (ReqBody k list a) api) | |
data FormUrlEncoded :: * #
Accept * FormUrlEncoded | application/x-www-form-urlencoded |
ToForm a => MimeRender * FormUrlEncoded a |
|
FromForm a => MimeUnrender * FormUrlEncoded a |
|
Endpoint for plugging in your own Wai Application
s.
The given Application
will get the request as received by the server, potentially with
a modified (stripped) pathInfo
if the Application
is being routed with :>
.
In addition to just letting you plug in your existing WAI Application
s,
this can also be used with serveDirectory to serve
static files stored in a particular directory on your filesystem
HasForeign k lang ftype Raw | |
type Foreign ftype Raw | |
data Header sym a :: Symbol -> * -> * #
Extract the given header's value as a value of type a
.
Example:
>>>
newtype Referer = Referer Text deriving (Eq, Show)
>>>
>>>
-- GET /view-my-referer
>>>
type MyApi = "view-my-referer" :> Header "from" Referer :> Get '[JSON] Referer
(KnownSymbol sym, HasForeignType * k lang ftype a, HasForeign k lang ftype api) => HasForeign k lang ftype ((:>) * * (Header sym a) api) | |
(KnownSymbol h, ToHttpApiData v) => AddHeader h v (Headers ((:) * fst rest) a) (Headers ((:) * (Header h v) ((:) * fst rest)) a) | |
Functor (Header sym) | |
(KnownSymbol h, ToHttpApiData x, GetHeaders (HList xs)) => GetHeaders (HList ((:) * (Header h x) xs)) | |
HasForeignType Symbol * Python Text a => HasForeignType * * Python Text [Header a b] # | |
HasForeignType Symbol * Python Text a => HasForeignType * * Python Text (Headers ((:) * (Header a b) ([] *)) c) # | |
Eq a => Eq (Header sym a) | |
Show a => Show (Header sym a) | |
(KnownSymbol h, GetHeaders (HList rest), ToHttpApiData v) => GetHeaders (Headers ((:) * (Header h v) rest) a) | |
HasForeignType Symbol * Python Text a => HasForeignType (* -> *) * Python Text (Header a) # | |
(FromHttpApiData v, BuildHeadersTo xs, KnownSymbol h) => BuildHeadersTo ((:) * (Header h v) xs) | |
type Foreign ftype ((:>) * * (Header sym a) api) | |