GithubHelp home page GithubHelp logo

cwendt94 / espn-api Goto Github PK

View Code? Open in Web Editor NEW
530.0 19.0 178.0 5.71 MB

ESPN Fantasy API! (Football, Basketball)

License: MIT License

Python 99.39% Dockerfile 0.61%
fantasy football espn api basketball

espn-api's Introduction

codecov Join the chat at https://gitter.im/ff-espn-api/community PyPI version

ESPN API

This package uses ESPN's Fantasy API to extract data from any public or private league for Fantasy Football and Basketball (NHL, MLB, and WNBA are in development).
Please feel free to make suggestions, bug reports, and pull request for features or fixes!

This package was inspired and based off of rbarton65/espnff.

Installing

With Git:

git clone https://github.com/cwendt94/espn-api
cd espn-api
python3 setup.py install

With pip:

pip install espn_api

Usage

# Football API
from espn_api.football import League
# Basketball API
from espn_api.basketball import League
# Hockey API
from espn_api.hockey import League
# Baseball API
from espn_api.baseball import League
# Init
league = League(league_id=222, year=2019)

Run Tests

python3 setup.py nosetests

If you have any questions about the package, ESPN API data, or want to talk about a feature please start a discussion!

Issue Reporting

If you find a bug follow the steps below for reporting.

  1. Open a new issue with a brief description of the bug for the title. In the title also add which sport (Football or Basketball)

  2. Run the application in debug mode to view ESPN API request's and response's

    # ... import statement above
    league = League(league_id=1245, year=2019, debug=True)

    The application will print all requests and the response from ESPN's API in the console. I would suggest piping the console output to a text file as it will be a lot of data.

  3. Find the last log before the crash and copy it in the issue descrption with the line number of the crash or possible bug.

  4. Submit the new issue!

I will try to comment on the issue as soon as possible with my thoughts and possible fix!

espn-api's People

Contributors

austinegri avatar barbacbd avatar benlawson avatar bnm91 avatar brownrw8 avatar bsmiller25 avatar cdchan avatar cjwin2000 avatar ctmarxen avatar cwendt94 avatar danslocum avatar desipilla avatar dtcarls avatar gitter-badger avatar jelias2 avatar joelataccelm avatar joeyagreco avatar johncheng2011 avatar kjeldgaard avatar kmanc avatar nabraham avatar petergottesman avatar samthom1 avatar simonbilskyrollins avatar smkuehnhold avatar spkane31 avatar tkauffman42 avatar willfeltman avatar zackwebb 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

espn-api's Issues

POSITION_MAP[pos] KeyError: 25

When creating a league player.py throws a KeyError:

File "C:\********\packages\ff_espn_api\player.py", line 18, in __init__
    if '/' not in POSITION_MAP[pos] or '/' in self.name:
KeyError: 25

KeyError: 'away' on box scores

This may very well be pebkac but when I try to pull any box scores I get a KeyError. I can pull other league settings without issue but it seems to break at this point.

Something like the following will throw the following error:
box_scores = league.box_scores()
print (box_scores)

Traceback (most recent call last): File "test.py", line 9, in <module> box_scores = league.box_scores(week=3) File "/Users/john.peterson/Documents/FF/venv/lib/python3.7/site-packages/ff_espn_api/league.py", line 313, in box_scores box_data = [BoxScore(matchup) for matchup in schedule] File "/Users/john.peterson/Documents/FF/venv/lib/python3.7/site-packages/ff_espn_api/league.py", line 313, in <listcomp> box_data = [BoxScore(matchup) for matchup in schedule] File "/Users/john.peterson/Documents/FF/venv/lib/python3.7/site-packages/ff_espn_api/box_score.py", line 8, in __init__ self.away_team = data['away']['teamId'] KeyError: 'away'

Is there a way to just pull the league data object to parse and see if it is being returned in a different structure? Fwiw its a private league.

Thank you for putting this together, its wonderful.

Better documentation and usage of API

I would like to split out usage and API functions from the README.

Make it easier for someone to come in and see all of the classes and variables without going through the code

Team ids not incremental?

when importing team data, I am having a difficult time working with the team ids. In some leagues (not all), the team ids are not incremental.

{1: ['Antonio Pisano', 'Le’Veon On A Prayer '], 2: ['Anthony Gallo', 'Hepititis A'], 4: ['Mark Farrell', 'The Magic Pen Factory'], 5: ['Anthony Gallo', 'New York bELIevers'], 6:... }

The first team has an id of 1, the second team has an id of 2, but the third team has an id of 4. The rest of the ids increment normally up to 13 (for this 12 person league). Team two only has one owner, not two (which I thought could be causing the issue).

Thanks for any help

How do you use this with your website?

Not sure if it's appropriate to post this as an issue, but I was curious what you use for your league's website (you mention that you use this codebase for your own website), and/or how you use this codebase? I have been playing around with Django, but I'm not entirely sure of the best way to use this repo effectively with Django. I'm also a novice :)

Recent Activity improvements

Our league differentiates (for keeper purposes) whether someone picks someone up via Waivers vs. via Free agency.

Would it be possible to add the difference when looking at recent activity?

Similar to only seeing trades, can there be a setting to only see "added" or "added by waivers"?

And finally, we are moving to FAAB next year (and would like to tie keeper values to FAAB spent), would it be possible to add in the monetary value of the waiver addition?

Thanks for an awesome API!

Get player's score for a certain week

When using the parameter {'scoringPeriodId': 2} to fetch stats for a given week, the player's score is returned as the player's season total, not his weekly total. When the scoringPeriodId parameter is not used, the current week's stats are collected and the current points for a player is his weekly total. How can I get a weekly total for a week that has already passed?

>> matchups = requests.get(url, cookies = cookies, params = {'view' : 'mMatchup', 'scoringPeriodId': 2}).json()
# See Lamar Jackson's stats for week 2
>> matchups['teams'][0]['roster']['entries'][16]['playerPoolEntry']['appliedStatTotal']
64.44
# 64.44 is his season total, not his weekly total

Implement League Trades

Need to figure out how trades can be accessed and viewed with ESPN's new v3 API endpoint.

Unable to get projected points for 2020 Season

I may be missing something regarding working with the 2020 season, but it seems as though there is not box_score information for the week 1 upcoming season 2020. I looked through the JSON views according to other posts and did not see a projected score per player, but on the app/site there are definitely projections for week 1, 2020. Is there another way to get the pre-season projections?

Looking to compare ESPN's player projections with other sites leading up to 2020.

Draft import key error: 0

New key error when importing draft using v1.1.0 in this leagueId=373956 Let me know what other information can be provided. I see 1 empty draft slot, but I thought this was resolved with #21

`2019-09-11T02:06:15.710208+00:00 app[worker.1]:     bot_main("init")
2019-09-11T02:06:15.710211+00:00 app[worker.1]:   File "ff_bot/ff_bot.py", line 284, in bot_main
2019-09-11T02:06:15.710388+00:00 app[worker.1]:     league = League(league_id, year)
2019-09-11T02:06:15.710391+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/ff_espn_api/league.py", line 54, in __init__
2019-09-11T02:06:15.710576+00:00 app[worker.1]:     self._fetch_league()
2019-09-11T02:06:15.710579+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/ff_espn_api/league.py", line 77, in _fetch_league
2019-09-11T02:06:15.710716+00:00 app[worker.1]:     self._fetch_draft()
2019-09-11T02:06:15.710723+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/ff_espn_api/league.py", line 195, in _fetch_draft
2019-09-11T02:06:15.710911+00:00 app[worker.1]:     playerName = self.player_map[playerId]
2019-09-11T02:06:15.710946+00:00 app[worker.1]: KeyError: 0
`

Add Draft Feature

Using ESPN's view=mDraftDetail endpoint extract the draft details of the current season.

statId lookup

This is more of an ESPN API question than an issue with your (very useful) package. But I believe getting an answer should be useful for potential further/future development of the package.

I'm looking to extract the scoring settings of my league. This can be done as follows:

ENDPOINT = f"https://fantasy.espn.com/apis/v3/games/FFL/seasons/{year}/segments/0/leagues/{leagueID}"
cookies = {'espn_s2': espn_s2,
                'SWID': swid}
params = {'view': 'mSettings'}
r = requests.get(ENDPOINT, params=params, cookies=cookies)
data = r.json()
scoringFormat = data['settings']['scoringSettings']['scoringItems']

scoringFormat is now a list, where each element looks roughly like this:

{'isReverseItem': False,
 'leagueRanking': 0.0,
 'leagueTotal': 0.0,
 'points': -0.5,
 'statId': 85}

This statId comes up in other parts of API too, but I have found no way of matching it to an actual metric, aside from going through manually and working it out based on my league's settings. scoringFormat is 47 elements long in my league and I'd like to be able to apply this to other leagues with different scoring format variations, so I'd prefer not to take the manual route.

Is there any way of retrieving some sort of lookup for this?

Datetime Format?

Do you know what Date-time format is being used by the API? My goal is to pull transactions for the past week. For example, in Recent-Activity...

import datetime
thyme = data[8]['messages'][0]['date']
datetime.datetime.fromtimestamp(thyme).strftime('%c')
--> 'Mon Jan 2 22:24:11 51708'

import time
time.localtime(thyme)
--> time.struct_time(tm_year=51708, tm_mon=1, tm_mday=2, tm_hour=22, tm_min=24, tm_sec=11, tm_wday=0, tm_yday=2, tm_isdst=0)

Breakdown of Points

Right now I don't see anyting more than Points for a player.boxscore. Is it possible to see from the ESPN api what the breakdown was for that player (yards, kicks, tds)?

Weekly Roster?

Is there a way to get rosters by week? I don't see this on the ESPN site, so I'm not especially hopeful.

Context is trying to calculate how many points on each team's roster came from draft, trade, and waiver pickups. I can probably reconstruct this from draft and activity, but it's nice that roster has it stored there already.

waiver wire

Sorry to keep asking questions, but I don't see anything about this in the code or docs: any way to pull from the daily waiver reports?

Issues with new Username authentication flow

Update

I'm not actually sure whats going on here, it seems to authenticate and then the request is rejected with a 401.

File "espnTool.py", line 188, in <module>
   displayMenu()
 File "espnTool.py", line 171, in displayMenu
   getScores()
 File "espnTool.py", line 40, in getScores
   league = League(leagueID, year, username, password)
 File "/usr/local/lib/python3.7/site-packages/ff_espn_api/league.py", line 55, in __init__
   self._fetch_league()
 File "/usr/local/lib/python3.7/site-packages/ff_espn_api/league.py", line 65, in _fetch_league
   checkRequestStatus(self.status)
 File "/usr/local/lib/python3.7/site-packages/ff_espn_api/league.py", line 24, in checkRequestStatus
   raise Exception("Access Denied")
Exception: Access Denied

IndexError: list index out of range when importing new League

IndexError Traceback (most recent call last)
in
----> 1 league_was_18 = League(was_id, year18, espn_s2, swid)

~\Anaconda3\lib\site-packages\ff_espn_api\league.py in init(self, league_id, year, espn_s2, swid)
52 'SWID': self.swid
53 }
---> 54 self._fetch_league()
55
56 def repr(self):

~\Anaconda3\lib\site-packages\ff_espn_api\league.py in _fetch_league(self)
74 self._fetch_settings()
75 self._fetch_players()
---> 76 self._fetch_teams()
77 self._fetch_draft()
78

~\Anaconda3\lib\site-packages\ff_espn_api\league.py in _fetch_teams(self)
119 member = None
120 break
--> 121 elif member['id'] == team['owners'][0]:
122 break
123 roster = team_roster[team['id']]

IndexError: list index out of range

KeyError: 'deadlineDate' when creating League object

Attempting to follow this example code:

from ff_espn_api import League
league_id = 1234
year = 2018
swid = '{03JFJHW-FWFWF-044G}'
espn_s2 = 'ASCWDWheghjwwqfwjqhgjkjgegkje'
league = League(league_id, year, espn_s2, swid)

I got this error:


  File "<ipython-input-26-f3f7b9b05a45>", line 6, in <module>
    league = League(league_id, year, espn_s2, swid)

  File "C:\Users\Oli\AppData\Local\Continuum\anaconda3\lib\site-packages\ff_espn_api\league.py", line 49, in __init__
    self._fetch_league()

  File "C:\Users\Oli\AppData\Local\Continuum\anaconda3\lib\site-packages\ff_espn_api\league.py", line 69, in _fetch_league
    self._fetch_settings()

  File "C:\Users\Oli\AppData\Local\Continuum\anaconda3\lib\site-packages\ff_espn_api\league.py", line 145, in _fetch_settings
    self.settings = Settings(data['settings'])

  File "C:\Users\Oli\AppData\Local\Continuum\anaconda3\lib\site-packages\ff_espn_api\settings.py", line 9, in __init__
    self.trade_deadline = data['tradeSettings']['deadlineDate']

KeyError: 'deadlineDate'

I'm pretty confident I've got the correct swid and espn_s2 values for my league, although my espn_s2 is 300 characters long compared to the example one with 29 characters..

Implement Free Agency List

For a given week, be able to get a list of players on free agency, similar to box player, slot_position could be 'FA'

Pull all scores?

Sorry if this is super basic, but is there a way to pull all player actual scores either for a given week or cumulatively? (This could be across the league or all of ESPN).

What I'm really interested in doing is comparing points and auction values, but am trying to start somewhere.

Up to date team projections

Hi, not sure how else to ask you so this is an issue (can be closed if having open ones bother you).

I'm currently trying to poke around and locate up to date matchup projections. I know that throughout the game the matchup screen in the app updates the projections to reflect how players have performed so far. I wanted to incorporate that information into an app that I'm working on, but found that the projected points in the box_player object will always reflect the value that was projected before the match began. I've been pouring through the various payloads but so far having a really tough time interpreting what the stats correlate to. Any advice you can share in terms of determining the values of certain data points, or have you thought any about where this info might be found? Since its displayed in the matchup view I figured there was a good chance it would be in box_scores, but I just can't figure out what any of the data points are.

KeyError: 'pointsByScoringPeriod'

I'm running into the following error when using the League.box_scores function for 2019 Week 1:

  File "/home/cdgarren/Projects/fantasyfootball/env/lib/python3.5/site-packages/ff_espn_api/league.py", line 309, in box_scores
    box_data = [BoxScore(matchup) for matchup in schedule if str(week) in matchup['home']['pointsByScoringPeriod']]
  File "/home/cdgarren/Projects/fantasyfootball/env/lib/python3.5/site-packages/ff_espn_api/league.py", line 309, in <listcomp>
    box_data = [BoxScore(matchup) for matchup in schedule if str(week) in matchup['home']['pointsByScoringPeriod']]
KeyError: 'pointsByScoringPeriod'

I'm working on migrating my homebrew scripts to use your module, and I was able to recreate what I needed while testing with the 2018 season. This occurs when I switch to 2019. So I'm not sure if this is stemming from an API change, or if this is due to the fact that the games for the Week 1 haven't started yet.

scoreboard and playoffs

Any idea if ESPN numbers the playoff weeks differently in league.scoreboard? I was trying to download all of our league's scores and a few years appear to have gaps in the sequence of weeks (e.g., pulling the matchups works for 1-12, 13-15 in 2015).

I don't remember there being bye weeks scheduled, but I'm wondering if something in the first round of playoffs is treated differently.

Other fantasy sports

@cwendt94 Are you interested in expanding this beyond fantasy football? I play fantasy football but I'm personally more invested in fantasy baseball and basketball.

I've created a fork where I took everything from here and moved it to a football submodule and started a minimalist (very minimalist for now) basketball submodule. Now instead of from ff_espn_api import League I can say either from espn_api.football import League or from espn_api.basketball import League. The submodule class names maybe should change but I just did this quickly as a proof of concept.

If you are interested I'd happily open a pull request (preferably to some dev branch) so the community can contribute here. Alternatively, I'll just continue working on my branch.

Feature request: Improvement to Free Agent endpoint

Currently, the endpoint does not grab all free agents. I'm not entirely sure what criteria is takes to when it returns a few free agents but it would be nice to have all of them plus box_player info on them. Will search on my end to see if feasible.

Feature Request: Add decimal places to the Box Score projections

Great work on the python API, it's really great. I'm in a league that does 0.1 points per yard for RB/WR/TE, and 0.04 points per yard thrown for QB. This causes the projections and scores to be translated as doubles, not straight integers. I noticed that the box_scores projections don't have decimal places. It would be nice if it did for leagues similar to ours.

Box Scores Lineup Order

Is there an order to the lineup? I can't seem to understand the array order.
For example, from the two teams of the same matchup:

matchup = box_scores[0]
print("Home Team")
for player in range(0, len(matchup.home_lineup)):
    print(matchup.home_lineup[player].name + "\t" + matchup.home_lineup[player].position)
print("\nAway Team")
for player in range(0, len(matchup.away_lineup)):
    print(matchup.away_lineup[player].name + "\t" + matchup.away_lineup[player].position)

Output:

Home Team
Michael Thomas  WR
Joe Mixon       RB
Derrick Henry   RB
Brandin Cooks   WR
Tyler Boyd      WR
Phillip Lindsay RB
Austin Ekeler   RB
Tarik Cohen     RB
Austin Hooper   TE
Ben Roethlisberger      QB
Donte Moncrief  WR
Stephen Gostkowski      K
Golden Tate     WR
Will Dissly     TE
Ravens D/ST     D/ST

Away Team
Christian McCaffrey     RB
Antonio Brown   WR
Devonta Freeman RB
Cooper Kupp     WR
Sony Michel     RB
Devin Singletary        RB
Matt Ryan       QB
Vance McDonald  TE
Rams D/ST       D/ST
Dante Pettis    WR
Courtland Sutton        WR
Tyrell Williams WR
Matt Bryant     K
Kalen Ballage   RB
Jaylen Samuels  RB

I assumed the lineup would follow ESPN lineup order with QB typically first, but I can't see a pattern to the order. Finding it hard to loop through lineup to calculate values like starter scores vs. bench scores.

"filterSlotIds":{"value":slot_filter} | free_agents

In the free_agents method, the "filterSlotIds" filter is causing the following error message from the ESPN API. Irrespective of the value provided in that field. Are you seeing the same?

{'cause': 'Cannot deserialize instance of java.util.ArrayList out of VALUE_STRING token\n at [Source: (String)"{"players": {"filterStatus": {"value": ["FREEAGENT", "WAIVERS"]}, "filterInjured": {"value": "false"}, "filterSlotIds": {"value": slot_filter}, "limit": 50, "sortPercOwned": {"sortPriority": 1, "sortAsc": false}, "sortDraftRanks": {"sortPriority": 100, "sortAsc": true, "value": "STANDARD"}}, "communication": {"topicsByType": {}}}"; line: 1, column: 131] (through reference chain: com.espn.fantasy.lm.filter.LeagueApiFilter$LeagueFilterParams["players"]->com.espn.fantasy.lm.filter.PlayerPoolEntryFilter$PlayerPoolFilterParams["filterSlotIds"]->com.espn.fantasy.lm.filter.ApiFilter$ParamValue["value"])',
'messages': ["Invalid parameter for 'LeagueFilterParams'."]}

box_player acquisition type

When a BoxPlayer object is constructed the acquisitionType is set to None. Is this fixable or just a problem in how the data is stored on ESPN's end?

Feature request: box scores

Is it possible to add box scores to the API? Then we could tabulate data on a points-per-player basis. That would be very interesting.

Exception: Access denied

I'm getting this access denied error when I try to set up the variable "League"
I'm sure it's something simple. I'm in Windows.

Can anyone help?
Thanks,

from ff_espn_api import League
import numpy as np

league_id = 88888
year = 2019
league = League(league_id, year)

image

Error when Trying to Pull Box Scores

Tryint to pull box score:

bs=(league.box_scores(1))
print(bs[1].home_team)

And getting the following Error:

File "C:/Users/rkuma343/Documents/Python_Scripts/Fantasy/take12.py", line 85, in players_matchup
bs=(league.box_scores(1))

File "C:\Users\rkuma343\Documents\Anaconda\lib\site-packages\ff_espn_api\league.py", line 309, in box_scores
box_data = [BoxScore(matchup) for matchup in schedule if str(week) in matchup['home']['pointsByScoringPeriod']]

File "C:\Users\rkuma343\Documents\Anaconda\lib\site-packages\ff_espn_api\league.py", line 309, in
box_data = [BoxScore(matchup) for matchup in schedule if str(week) in matchup['home']['pointsByScoringPeriod']]

KeyError: 'pointsByScoringPeriod'

Get rid of scoreboard feature

No need for scoreboard feature anymore. box_scores gets all of scoreboard data plus live points update and player points update

How to store each player as Player Object in recent_activity()

If I wanted to add players as a Player object into each Activity, how would you recommend this? Does it make sense to have an overarching PlayerPool list that is compiled during the fetch_teams method? This list can subsequently be searched by playerID and return the actual Player object into this activity?

My ultimate objective is to (a) fetch all activities during the last scoring period (done). (b) identify each of these player's points during that week (open)

Hence my idea of having the player as an Object from which I could fetch their points...

Get roster of previous week?

A team's roster is listed under ['rosterForMatchupPeriod']['entries'] or ['rosterForCurrentScoringPeriod']['entries'], but after a week has concluded, neither ['rosterForMatchupPeriod'] or ['rosterForCurrentScoringPeriod'] exist anymore, only ['pointsByScoringPeriod']. Where can I find the roster for a previous week?

KeyError: -1 when importing League

I'm in 4 leagues. I received this error for 2 of the 4 leagues with the same lines indicated.

KeyError Traceback (most recent call last)
in
----> 1 league_dynasty_18 = League(dynasty_id, year18, espn_s2, swid)

~\Anaconda3\lib\site-packages\ff_espn_api\league.py in init(self, league_id, year, espn_s2, swid)
52 'SWID': self.swid
53 }
---> 54 self._fetch_league()
55
56 def repr(self):

~\Anaconda3\lib\site-packages\ff_espn_api\league.py in _fetch_league(self)
75 self._fetch_players()
76 self._fetch_teams()
---> 77 self._fetch_draft()
78
79 def _fetch_teams(self):

~\Anaconda3\lib\site-packages\ff_espn_api\league.py in _fetch_draft(self)
192 team = self.get_team_data(pick['teamId'])
193 playerId = pick['playerId']
--> 194 playerName = self.player_map[playerId]
195 round_num = pick['roundId']
196 round_pick = pick['roundPickNumber']

KeyError: -1

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.