Skip to content

Commit 39a47c4

Browse files
committed
Initial commit
1 parent b4299bd commit 39a47c4

9 files changed

+197
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace FinancialModelingPrepApi.Abstractions
2+
{
3+
public interface IFinancialModelingPrepApiClient
4+
{
5+
}
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace FinancialModelingPrepApi.Abstractions.Models
2+
{
3+
public enum ApiVersion
4+
{
5+
v3,
6+
v4,
7+
}
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using FinancialModelingPrepApi.Abstractions;
2+
3+
namespace FinancialModelingPrepApi.Core
4+
{
5+
public class FinancialModelingPrepApiClient : IFinancialModelingPrepApiClient
6+
{
7+
8+
}
9+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Specialized;
3+
using System.Net.Http;
4+
using System.Threading.Tasks;
5+
6+
namespace FinancialModelingPrepApi.Core.Http
7+
{
8+
public class FinancialModelingPrepHttpClient
9+
{
10+
private readonly HttpClient client;
11+
private readonly FinancialModelingPrepOptions options;
12+
13+
public FinancialModelingPrepHttpClient(HttpClient client, FinancialModelingPrepOptions options)
14+
{
15+
this.client = client ?? throw new ArgumentNullException(nameof(client));
16+
this.options = options ?? throw new ArgumentNullException(nameof(options));
17+
18+
if (string.IsNullOrWhiteSpace(this.options.ApiKey))
19+
{
20+
throw new ArgumentException("'ApiKey' can not be null or empty");
21+
}
22+
}
23+
24+
public async Task<string> CallApiAsync(string urlPattern, NameValueCollection pathParams, QueryStringBuilder queryString)
25+
{
26+
PreProcessUrl(ref urlPattern, ref pathParams, ref queryString);
27+
28+
queryString.Add("apikey", options.ApiKey);
29+
30+
var requestUrl = $"{urlPattern}{queryString}";
31+
32+
using var response = await client.GetAsync(requestUrl);
33+
return await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
34+
}
35+
36+
private static void PreProcessUrl(ref string url, ref NameValueCollection pathParams, ref QueryStringBuilder qsb)
37+
{
38+
if (string.IsNullOrEmpty(url))
39+
{
40+
throw new ArgumentNullException(nameof(url));
41+
}
42+
43+
if (pathParams == null)
44+
{
45+
throw new ArgumentNullException(nameof(pathParams));
46+
}
47+
48+
qsb ??= new QueryStringBuilder();
49+
50+
if (pathParams.Count == 0)
51+
{
52+
return;
53+
}
54+
55+
foreach (string key in pathParams.Keys)
56+
{
57+
if (string.IsNullOrWhiteSpace(key))
58+
{
59+
throw new ArgumentException("Provided path parameter was null or empty");
60+
}
61+
else if (string.IsNullOrWhiteSpace(pathParams[key]))
62+
{
63+
throw new ArgumentException($"Provided path parameter value for {key} was null or empty");
64+
}
65+
else if (url.IndexOf($"[{key}]") < 0)
66+
{
67+
throw new ArgumentException($"Url pattern doesn't contain [{key}]");
68+
}
69+
70+
url = url.Replace($"[{key}]", pathParams[key]);
71+
}
72+
}
73+
}
74+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Collections.Specialized;
2+
3+
namespace FinancialModelingPrepApi.Core.Http
4+
{
5+
public class QueryStringBuilder
6+
{
7+
private readonly NameValueCollection queryParams;
8+
9+
public QueryStringBuilder()
10+
{
11+
queryParams = new NameValueCollection();
12+
}
13+
14+
public void Add(string key, object value)
15+
{
16+
if (string.IsNullOrEmpty(key))
17+
{
18+
return;
19+
}
20+
21+
var valueToAdd = value?.ToString().Trim();
22+
queryParams.Add(key, valueToAdd);
23+
}
24+
25+
public override string ToString()
26+
{
27+
if (queryParams.Count == 0)
28+
{
29+
return string.Empty;
30+
}
31+
32+
return $"?{queryParams}";
33+
}
34+
}
35+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using FinancialModelingPrepApi.Abstractions;
2+
using FinancialModelingPrepApi.Core;
3+
using FinancialModelingPrepApi.Core.Http;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.DependencyInjection.Extensions;
6+
using System;
7+
8+
namespace FinancialModelingPrepApi
9+
{
10+
public static class DependencyInjectionExtensions
11+
{
12+
public static void AddFinancialModelingPrepApiClient(this IServiceCollection services)
13+
{
14+
services.AddLogging();
15+
services.AddHttpClient<FinancialModelingPrepHttpClient>(client
16+
=> client.BaseAddress = new Uri("https://financialmodelingprep.com/api/"));
17+
services.TryAddSingleton<IFinancialModelingPrepApiClient, FinancialModelingPrepApiClient>();
18+
}
19+
}
20+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
9+
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
10+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31229.75
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinancialModelingPrepApi", "FinancialModelingPrepApi.csproj", "{B691C86E-CE23-40FA-811E-8D17BE9DD8BE}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{B691C86E-CE23-40FA-811E-8D17BE9DD8BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{B691C86E-CE23-40FA-811E-8D17BE9DD8BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{B691C86E-CE23-40FA-811E-8D17BE9DD8BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{B691C86E-CE23-40FA-811E-8D17BE9DD8BE}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {9A0E2AE7-CBFD-4C5C-89DF-A920130130FD}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace FinancialModelingPrepApi
2+
{
3+
public class FinancialModelingPrepOptions
4+
{
5+
public string ApiKey { get; set; } = "demo";
6+
}
7+
}

0 commit comments

Comments
 (0)